Skip to content

Commit

Permalink
Merge pull request #82 from Bdaya-Dev/feat/oidc-web-core
Browse files Browse the repository at this point in the history
feat: introduce package:oidc_web_core
  • Loading branch information
ahmednfwela authored Jun 8, 2024
2 parents b0ffeb4 + e61a223 commit 44a67c8
Show file tree
Hide file tree
Showing 74 changed files with 3,166 additions and 1,703 deletions.
21 changes: 16 additions & 5 deletions .github/workflows/dart_package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ name: Oidc Dart Package Workflow
on:
workflow_call:
inputs:
flutter_channel:
required: false
type: string
default: "stable"
flutter_version:
required: false
type: string
default: "3.22.0"
analyze_directories:
required: false
type: string
Expand Down Expand Up @@ -65,13 +73,15 @@ jobs:
- name: 📚 Git Checkout
uses: actions/checkout@v4

- name: 🎯 Setup Dart
uses: dart-lang/setup-dart@v1
- name: 🐦 Setup Flutter
uses: subosito/flutter-action@v2
with:
sdk: ${{inputs.dart_sdk}}
flutter-version: ${{inputs.flutter_version}}
channel: ${{inputs.flutter_channel}}
cache: true
cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }}

- name: 📦 Install Dependencies
run: dart pub get
- uses: bluefireteam/melos-action@v3

- name: ⚙️ Run Setup
if: "${{inputs.setup != ''}}"
Expand All @@ -81,6 +91,7 @@ jobs:
run: dart format --set-exit-if-changed .

- name: 🕵️ Analyze
continue-on-error: true
run: dart analyze --fatal-warnings ${{inputs.analyze_directories}}

- name: 🧪 Run Tests
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/flutter_package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ on:
flutter_version:
required: false
type: string
default: "3.13.2"
default: "3.22.0"
min_coverage:
required: false
type: number
Expand Down Expand Up @@ -89,6 +89,7 @@ jobs:
run: dart format --set-exit-if-changed lib test

- name: 🕵️ Analyze
continue-on-error: true
run: flutter analyze ${{inputs.analyze_directories}}

- name: 🧪 Run Tests
Expand Down
19 changes: 12 additions & 7 deletions .github/workflows/oidc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,20 @@ jobs:
uses: bluefireteam/melos-action@v3

- name: Run Chromedriver
run: |
git clone https://github.com/Bdaya-Dev/web_installers --branch new-chromedriver-urls
cd web_installers/packages/web_drivers
dart pub get
dart lib/web_driver_installer.dart chromedriver &
# ./chromedriver/chromedriver --port=4444 &
uses: nanasess/setup-chromedriver@v2
- run: chromedriver --port=4444 & sleep 5


# - name: Run Chromedriver
# run: |
# git clone https://github.com/Bdaya-Dev/web_installers --branch new-chromedriver-urls
# cd web_installers/packages/web_drivers
# dart pub get
# dart lib/web_driver_installer.dart chromedriver &
# # ./chromedriver/chromedriver --port=4444 &

- name: Integration Tests
run: flutter drive --driver test_driver/integration_test.dart --target integration_test/app_test.dart -d web-server --browser-name=chrome
run: flutter drive -v --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d web-server --browser-name=chrome

windows:
runs-on: windows-2019
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/oidc_core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:

build:
name: build
uses: ./.github/workflows/flutter_package.yaml
uses: ./.github/workflows/dart_package.yaml
with:
working_directory: packages/oidc_core
min_coverage: 0
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/oidc_web_core.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: oidc_web_core

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
pull_request:
paths:
- ".github/workflows/oidc_web_core.yaml"
- "packages/oidc_web_core/**"
push:
branches:
- main

jobs:

build:
name: build
uses: ./.github/workflows/dart_package.yaml
with:
working_directory: packages/oidc_web_core
min_coverage: 0
platform: chrome
custom_tests: |
dart pub global activate remove_from_coverage
dart pub global run remove_from_coverage:remove_from_coverage -f coverage/lcov.info -r '\.g\.dart$'
pana:
uses: ./.github/workflows/pana.yaml
needs: build
with:
min_score: 100

25 changes: 22 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,26 @@
"version": "0.2.0",
"configurations": [
{
"name": "example web",
"name": "example dart CLI",
"cwd": "packages/oidc_core",
"request": "launch",
"type": "dart",
"deviceId": "chrome",
"program": "example/main.dart",
},
{
"name": "example dart web",
"cwd": "packages/oidc_web_core/example",
"request": "launch",
"type": "dart",
"deviceId": "chrome",
"program": "web",
"args": [
"web:22433"
],
},
{
"name": "example flutter web",
"cwd": "packages/oidc/example",
"request": "launch",
"type": "dart",
Expand All @@ -16,7 +35,7 @@
],
},
{
"name": "example web server",
"name": "example flutter web server",
"cwd": "packages/oidc/example",
"request": "launch",
"type": "dart",
Expand All @@ -27,7 +46,7 @@
],
},
{
"name": "example",
"name": "example flutter",
"cwd": "packages/oidc/example",
"request": "launch",
"type": "dart",
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ This is a federated plugin split into the following main packages:

- [oidc](oidc-getting-started.md): Ready to use flutter plugin that conforms to the OIDC spec. ([pub.dev](https://pub.dev/packages/oidc))
- [oidc_core](oidc_core.md): Pure dart package that contains models and helpers for implementing the OIDC spec. ([pub.dev](https://pub.dev/packages/oidc_core))
- [oidc_web_core](oidc_web_core.md): Pure dart package based on [package:web](https://pub.dev/packages/web) which allows. ([pub.dev](https://pub.dev/packages/oidc_web_core))
- [oidc_default_store](oidc_default_store.md): An implementation of `OidcStore` that uses [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) and [shared_preferences](https://pub.dev/packages/shared_preferences). ([pub.dev](https://pub.dev/packages/oidc_default_store))
- [oidc_loopback_listener](oidc_loopback_listener.md): A pure dart package that creates a simple http server. ([pub.dev](https://pub.dev/packages/oidc_loopback_listener))

Expand Down
2 changes: 1 addition & 1 deletion docs/oidc-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ after following this document, you can check the [Usage Document](oidc-usage.md)
## Adding dependencies

```sh
dart pub add oidc oidc_default_store
dart pub add oidc oidc_default_store oidc_core
```

every platform you support has its own configuration and set up.
Expand Down
7 changes: 0 additions & 7 deletions docs/oidc-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,6 @@ manager.events().listen((event) {
});
```

#### OidcEvent

The base class for all events, this contains an `at` property that stores when the event occurred.

#### OidcPreLogoutEvent

Occurs before a user is forgotten, either via `forgetUser()` or via `logout()`.


### Refreshing the token manually
Expand Down
30 changes: 24 additions & 6 deletions docs/oidc_core.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# Using the Package <!-- omit from toc -->

[![package:oidc_core][package_image]][package_link]
# [![package:oidc_core][package_image]][package_link]

This is the core package written in pure dart, and maps the oidc spec to dart classes.

Note that you don't need to use this package if you are using the `OidcUserManager` from `package:oidc`, but it's useful to learn about it.

you can check the [CLI example](https://github.com/Bdaya-Dev/oidc/blob/main/packages/oidc_core/example/oidc_core_example.dart), showing how to use this package to implement the auth code flow in a CLI environment.
you can check the [CLI example](https://github.com/Bdaya-Dev/oidc/blob/main/packages/oidc_core/example/main.dart), showing how to use this package to implement the auth code flow in a CLI environment.

## OidcUtils

Expand Down Expand Up @@ -38,14 +36,33 @@ this is an enum that contains all the possible namespaces

On the web platform, since we use an external `redirect.html` page, implementations of the store MUST match the used page.

we made a default implementation in [package:oidc_default_store](oidc_default_store.md), which matches the `redirect.html` page provided in our examples.
we made a default implementation in [package:oidc_default_store](oidc_default_store.md) and [package:oidc_web_core](oidc_web_store.md), which matches the `redirect.html` page provided in our examples.

### OidcMemoryStore

A simple implementation of `OidcStore`, used mainly on CLI apps and for testing.

It stores everything in memory, and doesn't persist anything.

## OidcUserManagerBase

An abstract class containing all the base logic needed to implement oidc spec and maintain a user, regardless of platform.

Example implementations:

- CLI: example [here](https://github.com/Bdaya-Dev/oidc/blob/main/packages/oidc_core/example/cli_user_manager.dart)
- Flutter: `OidcUserManager` in [package:oidc](https://github.com/Bdaya-Dev/oidc/blob/main/packages/oidc/lib/src/managers/user_manager.dart)
- Dart Web: `OidcUserManagerWeb` in [package:oidc_web_core](https://github.com/Bdaya-Dev/oidc/blob/main/packages/oidc_web_core/lib/src/user_manager_web.dart)


## OidcEvent

The base class for all events, this contains an `at` property that stores when the event occurred.

### OidcPreLogoutEvent

Occurs before a user is forgotten, either via `forgetUser()` or via `logout()`.

## OidcPkcePair

you can use this to generate PKCE key pairs.
Expand Down Expand Up @@ -147,6 +164,7 @@ Contains methods that help you implement the OIDC spec yourself.
- `userInfo`: sends a request to the `/userinfo` endpoint.
- `deviceAuthorization`: sends a request to the device authorization endpoint.

---

[package_link]: https://pub.dev/packages/oidc_core
[package_image]: https://img.shields.io/badge/package-oidc__core-0175C2?logo=dart&logoColor=white
6 changes: 6 additions & 0 deletions docs/oidc_memory_store.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
part of [![package:oidc_core][package_image]][package_link]

A simple in-memory store useful for testing and CLI apps when persisting is not needed.

[package_link]: https://pub.dev/packages/oidc_core
[package_image]: https://img.shields.io/badge/package-oidc__core-0175C2?logo=dart&logoColor=white
116 changes: 116 additions & 0 deletions docs/oidc_web_core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# [![package:oidc_web_core][package_image]][package_link]

An alternative to `package:oidc` for dart web apps, that does NOT depend on flutter.

This can be used in things like [ngdart](https://pub.dev/packages/ngdart).

The package uses [package:web](https://dart.dev/interop/js-interop/package-web) to access browser APIs, making it also WASM compatible.

Learn more about developing dart web apps in: [dart.dev/web](https://dart.dev/web)

## Getting started

The setup here is similar to what is done in [package:oidc](/oidc-getting-started/#web)

### Add the dependencies

```bash
dart pub add oidc_web_core oidc_core
```

### Add redirect.html page

You need a separate html page to be delivered with your app, which will handle oidc-related requests.

you can get the page from the example project:

[redirect.html](https://github.com/Bdaya-Dev/oidc/blob/main/packages/oidc/example/web/redirect.html)

it doesn't matter where you put the page and what you call it, but it MUST be delivered from your redirect_uri

for example, here is a common configuration using this page:

```dart
final htmlPageLinkDevelopment = Uri.parse('http://127.0.0.1:22433/redirect.html');
final htmlPageLinkProduction = Uri.parse('https://mywebsite.com/redirect.html');
final htmlPageLink = kDebugMode ? htmlPageLinkDevelopment : htmlPageLinkProduction;
final redirectUri = htmlPageLink;
final postLogoutRedirectUri = htmlPageLink;
final frontChannelLogoutUri = htmlPageLink.replace(
queryParameters: {
...htmlPageLink.queryParameters,
'requestType': 'front-channel-logout'
}
);
```

Note how `frontChannelLogoutUri` needs `requestType=front-channel-logout` for the page to know the request type.

you will have to register these urls with the openid provider first, depending on your configuration.

also the html page is completely customizable, but it's preferred to leave the javascript part as is, since it's well-integrated with the plugin.

## Usage

using this package is identical to [package:oidc](/oidc-usage/)

you can also see an [example here](https://github.com/Bdaya-Dev/oidc/tree/main/packages/oidc_web_core/example) of a dart web app using this package

1. Define the manager
```dart
final manager = OidcUserManagerWeb.lazy(
discoveryDocumentUri: OidcUtils.getOpenIdConfigWellKnownUri(
Uri.parse('https://demo.duendesoftware.com'),
),
// this is a public client,
// so we use [OidcClientAuthentication.none] constructor.
clientCredentials: const OidcClientAuthentication.none(
clientId: 'interactive.public.short',
),
// Use a web-only store
store: const OidcWebStore(),
settings: OidcUserManagerSettings(
frontChannelLogoutUri: Uri(path: 'redirect.html'),
uiLocales: ['en', 'ar'],
refreshBefore: (token) {
return const Duration(seconds: 1);
},
// scopes supported by the provider and needed by the client.
scope: ['openid', 'profile', 'email', 'offline_access'],
// this url must be an actual html page.
// see the file in /web/redirect.html for an example.
//
// for debugging in flutter, you must run this app with --web-port 22433
postLogoutRedirectUri: Uri.parse('http://127.0.0.1:22433/redirect.html'),
redirectUri: Uri.parse('http://127.0.0.1:22433/redirect.html'),
),
);
```
2. Init the manager
```dart
await manager.init();
```
3. Access the user
```dart
manager.userChanges().listen((user) {});
```
or
```dart
manager.currentUser;
```
4. Login
```dart
final user = await manager.loginAuthorizationCodeFlow();
```
5. Logout
```dart
await manager.logout();
```
---
[package_link]: https://pub.dev/packages/oidc_web_core
[package_image]: https://img.shields.io/badge/package-oidc__web__core-0175C2?logo=dart&logoColor=white
Loading

0 comments on commit 44a67c8

Please sign in to comment.