Skip to content

Commit

Permalink
Merge pull request #89 from Bdaya-Dev/fix/offline-cache-handling
Browse files Browse the repository at this point in the history
feat: support offline auth
  • Loading branch information
ahmednfwela authored Jun 9, 2024
2 parents a717098 + a60158c commit 71e6699
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 139 deletions.
7 changes: 7 additions & 0 deletions docs/oidc-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,17 @@ an instance of `OidcStore`, we provide 3 types of stores out of the box, dependi
1. `OidcMemoryStore` from [package:oidc_core](oidc_core.md); which stores the auth state in memory (good for CLI apps or during testing).
2. `OidcDefaultStore` from [package:oidc_default_store](oidc_default_store.md); which persists the auth state on disk or `localStorage` on web, And tries to encrypt the data if possible.
3. `OidcWebStore` from [package:oidc_web_core](oidc_web_core.md); which persists the auth state on `localStorage`/`session_storage` on web.
#### settings
settings to control the behavior of the instance.
- `bool supportOfflineAuth = false`: whether the app should keep expired tokens if it's not able to contact the server.
!!! Warning
Enabling offline auth can be a security risk, as it allows the app to keep tokens that are no longer valid.
And it may open up unexpected attack vectors.
- `bool strictJwtVerification = false`: whether JWTs are strictly verified.
- `Uri redirectUri`: the redirect uri that was configured with the provider.
- `Uri? postLogoutRedirectUri`: the post logout redirect uri that was configured with the provider.
Expand Down
4 changes: 2 additions & 2 deletions docs/oidc_web_core.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Learn more about developing dart web apps in: [dart.dev/web](https://dart.dev/we

## Getting started

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

### Add the dependencies

Expand Down Expand Up @@ -54,7 +54,7 @@ also the html page is completely customizable, but it's preferred to leave the j

## Usage

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

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

Expand Down
4 changes: 3 additions & 1 deletion packages/oidc/example/lib/app_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ final duendeManager = OidcUserManager.lazy(
refreshBefore: (token) {
return const Duration(seconds: 1);
},

strictJwtVerification: true,
// set to true to enable offline auth
supportOfflineAuth: false,
// scopes supported by the provider and needed by the client.
scope: ['openid', 'profile', 'email', 'offline_access'],
postLogoutRedirectUri: kIsWeb
Expand Down
47 changes: 26 additions & 21 deletions packages/oidc/example/lib/pages/auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,27 +104,32 @@ class _AuthPageState extends State<AuthPage> {
child: const Text('login with Resource owner grant'),
),
const Divider(),
DropdownButton<OidcPlatformSpecificOptions_Web_NavigationMode>(
hint: const Text('Web Navigation Mode'),
items: OidcPlatformSpecificOptions_Web_NavigationMode.values
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e.name),
),
)
.toList(),
value: webNavigationMode,
onChanged: (value) {
if (value == null) {
return;
}
setState(() {
webNavigationMode = value;
});
},
),
const Divider(),
if (kIsWeb) ...[
Text(
'Login Web Navigation Mode',
style: Theme.of(context).textTheme.headlineSmall,
),
DropdownButton<OidcPlatformSpecificOptions_Web_NavigationMode>(
items: OidcPlatformSpecificOptions_Web_NavigationMode.values
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e.name),
),
)
.toList(),
value: webNavigationMode,
onChanged: (value) {
if (value == null) {
return;
}
setState(() {
webNavigationMode = value;
});
},
),
const Divider(),
],
ElevatedButton(
onPressed: () async {
final messenger = ScaffoldMessenger.of(context);
Expand Down
30 changes: 15 additions & 15 deletions packages/oidc/example/lib/pages/secret_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,22 @@ class _SecretPageState extends State<SecretPage> {
},
),
),
ElevatedButton(
onPressed: () async {
await app_state.currentManager.logout(
//after logout, go back to home
originalUri: Uri.parse('/'),
options: OidcPlatformSpecificOptions(
web: OidcPlatformSpecificOptions_Web(
navigationMode: webNavigationMode,
),
),
);
},
child: const Text('Logout'),
),
const Divider(),
],
ElevatedButton(
onPressed: () async {
await app_state.currentManager.logout(
//after logout, go back to home
originalUri: Uri.parse('/'),
options: OidcPlatformSpecificOptions(
web: OidcPlatformSpecificOptions_Web(
navigationMode: webNavigationMode,
),
),
);
},
child: const Text('Logout'),
),
const Divider(),
Wrap(
spacing: 8,
children: [
Expand Down
1 change: 1 addition & 0 deletions packages/oidc_core/lib/src/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ class OidcConstants_Store {
static const expiresAt = 'expiresAt';
static const expiresInReferenceDate = 'expiresInReferenceDate';
static const currentUserAttributes = 'userAttributes';
static const currentUserInfo = 'userInfo';
static const originalUri = 'original_uri';
static const operationDiscriminator = 'operationDiscriminator';

Expand Down
1 change: 1 addition & 0 deletions packages/oidc_core/lib/src/managers/_exports.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'jwks_store_loader.dart';
export 'token_events.dart';
export 'user_manager_base.dart';
36 changes: 36 additions & 0 deletions packages/oidc_core/lib/src/managers/jwks_store_loader.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:jose_plus/jose.dart';
import 'package:oidc_core/oidc_core.dart';

class OidcJwksStoreLoader extends DefaultJsonWebKeySetLoader {
OidcJwksStoreLoader({
required this.store,
super.cacheExpiry,
super.httpClient,
});

/// The store to check first for the cached jws
final OidcStore store;

@override
Future<String> readAsString(Uri uri) async {
try {
final result = await super.readAsString(uri);
await store.set(
OidcStoreNamespace.discoveryDocument,
key: uri.toString(),
value: result,
);
return result;
} catch (e) {
//
final cached = await store.get(
OidcStoreNamespace.discoveryDocument,
key: uri.toString(),
);
if (cached != null) {
return cached;
}
rethrow;
}
}
}
Loading

0 comments on commit 71e6699

Please sign in to comment.