@strivacity/sdk-nuxt 4.0.0-beta.1 → 4.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -101
- package/dist/module.mjs +5 -4
- package/package.json +2 -2
- package/project.json +3 -0
- package/src/module.ts +7 -3
- package/src/runtime/composables/use-native-login.ts +27 -159
- package/src/runtime/composables/use-strivacity.ts +217 -67
- package/src/runtime/middleware/auth.server.ts +10 -1
- package/src/runtime/plugins/strivacity.client.ts +17 -0
- package/src/runtime/server/plugins/auth.server.ts +66 -30
- package/src/runtime/storages/default.ts +22 -67
- package/src/runtime/types.ts +7 -36
- package/src/runtime/utils/core.ts +2 -0
- package/testing/stubs/app.ts +8 -0
- package/testing/tests/composables.spec.ts +104 -3
- package/testing/tests/module.spec.ts +46 -0
- package/testing/tests/server/plugin.spec.ts +48 -10
- package/testing/tests/server/routes.spec.ts +2 -2
- package/.nuxt/app-component.mjs +0 -1
- package/.nuxt/app.config.mjs +0 -21
- package/.nuxt/component-chunk.mjs +0 -1
- package/.nuxt/component-names.mjs +0 -1
- package/.nuxt/components.d.ts +0 -66
- package/.nuxt/components.islands.mjs +0 -8
- package/.nuxt/components.plugin.mjs +0 -5
- package/.nuxt/css.mjs +0 -0
- package/.nuxt/error-component.mjs +0 -1
- package/.nuxt/fetch.d.ts +0 -1
- package/.nuxt/fetch.mjs +0 -8
- package/.nuxt/global-polyfills.mjs +0 -4
- package/.nuxt/imports.d.ts +0 -41
- package/.nuxt/imports.mjs +0 -42
- package/.nuxt/island-renderer.mjs +0 -2
- package/.nuxt/layouts.mjs +0 -2
- package/.nuxt/manifest/meta/b2d6b125-90fd-44d4-9916-0898f71676da.json +0 -1
- package/.nuxt/middleware.mjs +0 -7
- package/.nuxt/nitro.client.mjs +0 -2
- package/.nuxt/nuxt.config.mjs +0 -103
- package/.nuxt/nuxt.d.ts +0 -19
- package/.nuxt/nuxt.node.d.ts +0 -13
- package/.nuxt/nuxt.shared.d.ts +0 -7
- package/.nuxt/pages.mjs +0 -2
- package/.nuxt/paths.mjs +0 -15
- package/.nuxt/plugins.client.mjs +0 -14
- package/.nuxt/plugins.server.mjs +0 -10
- package/.nuxt/root-component.mjs +0 -1
- package/.nuxt/route-rules.mjs +0 -22
- package/.nuxt/router.options.mjs +0 -2
- package/.nuxt/schema/nuxt.schema.d.ts +0 -17
- package/.nuxt/schema/nuxt.schema.json +0 -3
- package/.nuxt/test-component-wrapper.mjs +0 -1
- package/.nuxt/tsconfig.app.json +0 -211
- package/.nuxt/tsconfig.json +0 -212
- package/.nuxt/tsconfig.node.json +0 -117
- package/.nuxt/tsconfig.server.json +0 -161
- package/.nuxt/tsconfig.shared.json +0 -165
- package/.nuxt/types/app.config.d.ts +0 -35
- package/.nuxt/types/build.d.ts +0 -0
- package/.nuxt/types/builder-env.d.ts +0 -1
- package/.nuxt/types/components.d.ts +0 -71
- package/.nuxt/types/imports.d.ts +0 -2
- package/.nuxt/types/layouts.d.ts +0 -16
- package/.nuxt/types/middleware.d.ts +0 -11
- package/.nuxt/types/modules.d.ts +0 -59
- package/.nuxt/types/nitro-config.d.ts +0 -14
- package/.nuxt/types/nitro-imports.d.ts +0 -20
- package/.nuxt/types/nitro-layouts.d.ts +0 -17
- package/.nuxt/types/nitro-nuxt.d.ts +0 -75
- package/.nuxt/types/nitro-routes.d.ts +0 -38
- package/.nuxt/types/nitro.d.ts +0 -3
- package/.nuxt/types/plugins.d.ts +0 -30
- package/.nuxt/types/runtime-config.d.ts +0 -38
- package/.nuxt/types/shared-app.config.d.ts +0 -28
- package/.nuxt/types/shared-imports.d.ts +0 -2
- package/.nuxt/types/vue-shim.d.ts +0 -0
- package/.nuxt/unhead-options.mjs +0 -5
- package/.nuxt/unhead.config.mjs +0 -1
- package/dist/module.d.mts +0 -7
- package/dist/module.json +0 -9
- package/dist/module.mjs.map +0 -1
- package/dist/runtime/composables/use-native-login-context.d.ts +0 -10
- package/dist/runtime/composables/use-native-login-context.js +0 -9
- package/dist/runtime/composables/use-native-login.d.ts +0 -10
- package/dist/runtime/composables/use-native-login.js +0 -143
- package/dist/runtime/composables/use-session.d.ts +0 -8
- package/dist/runtime/composables/use-session.js +0 -2
- package/dist/runtime/composables/use-strivacity.d.ts +0 -9
- package/dist/runtime/composables/use-strivacity.js +0 -77
- package/dist/runtime/middleware/auth.server.d.ts +0 -2
- package/dist/runtime/middleware/auth.server.js +0 -12
- package/dist/runtime/server/api/auth/backchannel-logout.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/backchannel-logout.get.js +0 -2
- package/dist/runtime/server/api/auth/callback.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/callback.get.js +0 -2
- package/dist/runtime/server/api/auth/entry.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/entry.get.js +0 -2
- package/dist/runtime/server/api/auth/login.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/login.get.js +0 -2
- package/dist/runtime/server/api/auth/logout.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/logout.get.js +0 -2
- package/dist/runtime/server/api/auth/refresh.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/refresh.get.js +0 -2
- package/dist/runtime/server/api/auth/register.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/register.get.js +0 -2
- package/dist/runtime/server/api/auth/revoke.get.d.ts +0 -2
- package/dist/runtime/server/api/auth/revoke.get.js +0 -2
- package/dist/runtime/server/composables/use-strivacity.d.ts +0 -2
- package/dist/runtime/server/composables/use-strivacity.js +0 -9
- package/dist/runtime/server/plugins/auth.server.d.ts +0 -10
- package/dist/runtime/server/plugins/auth.server.js +0 -66
- package/dist/runtime/server/utils/helpers.d.ts +0 -18
- package/dist/runtime/server/utils/helpers.js +0 -39
- package/dist/runtime/storages/core.d.ts +0 -1
- package/dist/runtime/storages/core.js +0 -13
- package/dist/runtime/storages/default.d.ts +0 -21
- package/dist/runtime/storages/default.js +0 -71
- package/dist/runtime/types.d.ts +0 -219
- package/dist/runtime/types.js +0 -1
- package/dist/runtime/utils/core.d.ts +0 -1
- package/dist/runtime/utils/core.js +0 -64
- package/dist/runtime/utils/noop.d.ts +0 -1
- package/dist/runtime/utils/noop.js +0 -3
- package/dist/types.d.mts +0 -9
- /package/src/runtime/server/api/auth/{backchannel-logout.get.ts → backchannel-logout.post.ts} +0 -0
package/README.md
CHANGED
|
@@ -111,7 +111,7 @@ export default defineNuxtConfig({
|
|
|
111
111
|
redirectUri: 'https://your-app.example.com/callback', // callback URL after authentication
|
|
112
112
|
scopes: ['openid', 'profile', 'email'], // requested user permissions/data
|
|
113
113
|
|
|
114
|
-
serverSessionUri: '/auth/login', //
|
|
114
|
+
serverSessionUri: '/auth/login', // Set to `null` for client-managed sessions - omitting this line still defaults to server-managed
|
|
115
115
|
secret: process.env.SECRET, // http-only cookie encryption key (random 32+ characters), required for server-managed sessions
|
|
116
116
|
postLoginRedirectUri: '/profile',
|
|
117
117
|
},
|
|
@@ -121,7 +121,7 @@ export default defineNuxtConfig({
|
|
|
121
121
|
The module automatically:
|
|
122
122
|
- registers `/auth/login`, `/auth/register`, `/auth/callback`, `/auth/refresh`, `/auth/revoke`, `/auth/entry`, `/auth/logout`, and `/auth/backchannel-logout` as Nitro server routes (see the table below)
|
|
123
123
|
- auto-imports `useStrivacity()`/`useNativeLogin()` on the client and `useStrivacity(event)` on the server - no import statements needed anywhere
|
|
124
|
-
- registers a global route middleware that resolves the session server-side before every render, so there's no separate provider component or session-prop wiring to do yourself
|
|
124
|
+
- with server-managed sessions, registers a global route middleware that resolves the session server-side before every render, so there's no separate provider component or session-prop wiring to do yourself. When the access token is within `refreshSkew` seconds of expiry and the session has a refresh token, the middleware refreshes it first (with the Server SDK's `getSession()`) and writes the rotated session cookie to the response; if the refresh fails, `useSession()` is `undefined`. Set `autoRefresh: false` in the Server SDK options to turn this off. The refresh token and ID token are removed (with `toClientSession()`) before the session is stored in `useSession()` (and serialized into the rendered HTML) - they stay in the server-side session
|
|
125
125
|
|
|
126
126
|
| Method | Path | Description | Response |
|
|
127
127
|
| ------ | --------------------------- | ---------------------------------------------------------- | -------------------------------------------- |
|
|
@@ -129,10 +129,10 @@ The module automatically:
|
|
|
129
129
|
| `GET` | `/auth/register` | Starts the registration flow and redirects to the IDP | `302` redirect to IDP |
|
|
130
130
|
| `GET` | `/auth/callback` | Completes authentication (handles the IDP callback) | `302` redirect or popup close script |
|
|
131
131
|
| `GET` | `/auth/refresh` | Refreshes the access token | `204 No Content` or `302` redirect |
|
|
132
|
-
| `GET` | `/auth/revoke` | Revokes tokens and clears the session | `
|
|
133
|
-
| `GET` | `/auth/logout` | Ends the session and redirects to the IDP logout page
|
|
134
|
-
| `GET` | `/auth/entry` | Handles external flow entry (e.g., password reset link) - embedded/native modes only |
|
|
135
|
-
| `POST` | `/auth/backchannel-logout` | Processes back-channel logout requests from the IDP | `
|
|
132
|
+
| `GET` | `/auth/revoke` | Revokes tokens and clears the session | `302` redirect to `postLogoutRedirectUri` |
|
|
133
|
+
| `GET` | `/auth/logout` | Ends the session and redirects to the IDP logout page; accepts a same-origin `?returnTo=` (default: `postLogoutRedirectUri`) | `302` to IDP logout (straight to `returnTo` when the session has no ID token) |
|
|
134
|
+
| `GET` | `/auth/entry` | Handles external flow entry (e.g., password reset link) - embedded/native modes only | `302` redirect to `loginUri` |
|
|
135
|
+
| `POST` | `/auth/backchannel-logout` | Processes back-channel logout requests from the IDP | `200 OK` (`400` invalid token, `501` storage without `deleteByLogoutToken`, `500` delete failed) |
|
|
136
136
|
|
|
137
137
|
> The `/auth` prefix and route names come from `authUrlPrefix` - see [Server configuration reference](#server-configuration-reference).
|
|
138
138
|
|
|
@@ -233,7 +233,7 @@ Forward the callback query string to `/auth/callback` - the Server SDK completes
|
|
|
233
233
|
<script setup lang="ts">
|
|
234
234
|
const route = useRoute();
|
|
235
235
|
|
|
236
|
-
await navigateTo({ path: '/auth/callback', query: route.query }, { redirectCode:
|
|
236
|
+
await navigateTo({ path: '/auth/callback', query: route.query }, { redirectCode: 302, external: true });
|
|
237
237
|
</script>
|
|
238
238
|
```
|
|
239
239
|
|
|
@@ -300,7 +300,7 @@ onMounted(() => {
|
|
|
300
300
|
|
|
301
301
|
**Server-managed sessions**:
|
|
302
302
|
|
|
303
|
-
With `serverSessionUri` configured, redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint:
|
|
303
|
+
With `serverSessionUri` configured, the `logout()` call above doesn't clear the server session cookie, so redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint, which then sends the user back to `postLogoutRedirectUri`. To land somewhere else, add a same-origin `?returnTo=` (e.g. `/auth/logout?returnTo=/goodbye`); a missing, invalid, or cross-origin value falls back to `postLogoutRedirectUri`. Whichever URL is used must be registered as an allowed post-logout redirect URI:
|
|
304
304
|
|
|
305
305
|
```vue
|
|
306
306
|
<!-- app/pages/logout.vue -->
|
|
@@ -342,7 +342,7 @@ async function onRevoke() {
|
|
|
342
342
|
|
|
343
343
|
**Server-managed sessions**:
|
|
344
344
|
|
|
345
|
-
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back:
|
|
345
|
+
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back. `sdk.refresh({ returnTo: '/profile' })` (`sdk` from `useStrivacity()`) performs the same refresh navigation for you:
|
|
346
346
|
|
|
347
347
|
```vue
|
|
348
348
|
<script setup lang="ts">
|
|
@@ -404,20 +404,23 @@ onMounted(async () => {
|
|
|
404
404
|
top: 100,
|
|
405
405
|
toolbar: false,
|
|
406
406
|
location: false,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
.then(() => navigate('/profile'))
|
|
412
|
-
.catch((error) => navigate(`/error?message=${encodeURIComponent(error.message)}`));
|
|
413
|
-
});
|
|
407
|
+
resizable: true,
|
|
408
|
+
scrollbars: true,
|
|
409
|
+
},
|
|
410
|
+
});
|
|
414
411
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
412
|
+
await router.push('/profile');
|
|
413
|
+
} catch (error) {
|
|
414
|
+
await router.push(`/error?message=${encodeURIComponent(error instanceof Error ? error.message : 'Unknown error')}`);
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
</script>
|
|
418
|
+
|
|
419
|
+
<template>
|
|
420
|
+
<section>
|
|
421
|
+
<h1>Opening login popup...</h1>
|
|
422
|
+
</section>
|
|
423
|
+
</template>
|
|
421
424
|
```
|
|
422
425
|
|
|
423
426
|
**Server-managed sessions**:
|
|
@@ -428,11 +431,30 @@ Popup mode always needs client-side JavaScript to open the window, so there's no
|
|
|
428
431
|
|
|
429
432
|
**Client-managed sessions**:
|
|
430
433
|
|
|
431
|
-
The
|
|
434
|
+
The pop-up still navigates to your `redirectUri`, so you still need a callback route there - without it nothing posts the result back to the opener. Call `handleCallback()` there; in popup mode it never resolves (the opener closes the pop-up once it receives the result), so don't rely on code after it running:
|
|
435
|
+
|
|
436
|
+
```vue
|
|
437
|
+
<!-- app/pages/callback.vue -->
|
|
438
|
+
<script setup lang="ts">
|
|
439
|
+
const { handleCallback } = useStrivacity();
|
|
440
|
+
|
|
441
|
+
onMounted(() => {
|
|
442
|
+
void handleCallback();
|
|
443
|
+
});
|
|
444
|
+
</script>
|
|
445
|
+
|
|
446
|
+
<template>
|
|
447
|
+
<section>
|
|
448
|
+
<h1>Logging in...</h1>
|
|
449
|
+
</section>
|
|
450
|
+
</template>
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
`login()` resolves in the opener once the result has been received and, for client-managed sessions, the tokens have been exchanged.
|
|
432
454
|
|
|
433
455
|
**Server-managed sessions**:
|
|
434
456
|
|
|
435
|
-
|
|
457
|
+
The callback page must not call `handleCallback()`: forward the query string to `/auth/callback` instead, as in the server-managed redirect callback. The Server SDK exchanges the code, sets the session cookie and responds with a page that posts the result to the opener and closes the pop-up.
|
|
436
458
|
|
|
437
459
|
##### Registration
|
|
438
460
|
|
|
@@ -510,7 +532,7 @@ onMounted(() => {
|
|
|
510
532
|
|
|
511
533
|
**Server-managed sessions**:
|
|
512
534
|
|
|
513
|
-
With `serverSessionUri` configured, redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint:
|
|
535
|
+
With `serverSessionUri` configured, the `logout()` call above doesn't clear the server session cookie, so redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint, which then sends the user back to `postLogoutRedirectUri`. To land somewhere else, add a same-origin `?returnTo=` (e.g. `/auth/logout?returnTo=/goodbye`); a missing, invalid, or cross-origin value falls back to `postLogoutRedirectUri`. Whichever URL is used must be registered as an allowed post-logout redirect URI:
|
|
514
536
|
|
|
515
537
|
```vue
|
|
516
538
|
<!-- app/pages/logout.vue -->
|
|
@@ -551,7 +573,7 @@ async function onRevoke() {
|
|
|
551
573
|
|
|
552
574
|
**Server-managed sessions**:
|
|
553
575
|
|
|
554
|
-
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back:
|
|
576
|
+
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back. `sdk.refresh({ returnTo: '/profile' })` (`sdk` from `useStrivacity()`) performs the same refresh navigation for you:
|
|
555
577
|
|
|
556
578
|
```vue
|
|
557
579
|
<script setup lang="ts">
|
|
@@ -974,7 +996,7 @@ onMounted(() => {
|
|
|
974
996
|
|
|
975
997
|
**Server-managed sessions**:
|
|
976
998
|
|
|
977
|
-
With `serverSessionUri` configured, redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint:
|
|
999
|
+
With `serverSessionUri` configured, the `logout()` call above doesn't clear the server session cookie, so redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint, which then sends the user back to `postLogoutRedirectUri`. To land somewhere else, add a same-origin `?returnTo=` (e.g. `/auth/logout?returnTo=/goodbye`); a missing, invalid, or cross-origin value falls back to `postLogoutRedirectUri`. Whichever URL is used must be registered as an allowed post-logout redirect URI:
|
|
978
1000
|
|
|
979
1001
|
```vue
|
|
980
1002
|
<!-- app/pages/logout.vue -->
|
|
@@ -1015,7 +1037,7 @@ async function onRevoke() {
|
|
|
1015
1037
|
|
|
1016
1038
|
**Server-managed sessions**:
|
|
1017
1039
|
|
|
1018
|
-
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back:
|
|
1040
|
+
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back. `sdk.refresh({ returnTo: '/profile' })` (`sdk` from `useStrivacity()`) performs the same refresh navigation for you:
|
|
1019
1041
|
|
|
1020
1042
|
```vue
|
|
1021
1043
|
<script setup lang="ts">
|
|
@@ -1064,7 +1086,6 @@ const { state, forms, messages, loading, submitForm, setFormValue } = useNativeL
|
|
|
1064
1086
|
params: {
|
|
1065
1087
|
prompt: 'login', // use 'create' to open the registration flow instead
|
|
1066
1088
|
language: 'en-US', // set the UI language (BCP 47 language tag)
|
|
1067
|
-
sdk: 'web-minimal', // rendering mode: 'web-minimal' for simplified rendering, 'web' (default) for full rendering hints and branding
|
|
1068
1089
|
sessionId: searchParams.get('session_id'), // pass a session ID to resume an existing flow
|
|
1069
1090
|
},
|
|
1070
1091
|
onLogin: async () => {
|
|
@@ -1270,7 +1291,7 @@ onMounted(() => {
|
|
|
1270
1291
|
|
|
1271
1292
|
**Server-managed sessions**:
|
|
1272
1293
|
|
|
1273
|
-
With `serverSessionUri` configured, redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint:
|
|
1294
|
+
With `serverSessionUri` configured, the `logout()` call above doesn't clear the server session cookie, so redirect to `/auth/logout` instead - the Server SDK clears the session and redirects to the IDP end-session endpoint, which then sends the user back to `postLogoutRedirectUri`. To land somewhere else, add a same-origin `?returnTo=` (e.g. `/auth/logout?returnTo=/goodbye`); a missing, invalid, or cross-origin value falls back to `postLogoutRedirectUri`. Whichever URL is used must be registered as an allowed post-logout redirect URI:
|
|
1274
1295
|
|
|
1275
1296
|
```vue
|
|
1276
1297
|
<!-- app/pages/logout.vue -->
|
|
@@ -1311,7 +1332,7 @@ async function onRevoke() {
|
|
|
1311
1332
|
|
|
1312
1333
|
**Server-managed sessions**:
|
|
1313
1334
|
|
|
1314
|
-
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back:
|
|
1335
|
+
With `serverSessionUri` configured, tokens are refreshed/revoked by the Server SDK - trigger it by navigating to the auth routes, then let it redirect back. `sdk.refresh({ returnTo: '/profile' })` (`sdk` from `useStrivacity()`) performs the same refresh navigation for you:
|
|
1315
1336
|
|
|
1316
1337
|
```vue
|
|
1317
1338
|
<script setup lang="ts">
|
|
@@ -1367,17 +1388,36 @@ const ctx = useStrivacity<RedirectFlow>();
|
|
|
1367
1388
|
accessTokenExpired: Ref<boolean>; // True once the access token has expired
|
|
1368
1389
|
accessTokenExpirationDate: Ref<number | null>; // Access token expiration timestamp
|
|
1369
1390
|
|
|
1370
|
-
// Methods (
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1391
|
+
// Methods (proxied to `sdk`; parameter/return types follow the flow type)
|
|
1392
|
+
init(): Promise<void>; // Load metadata and restore any persisted session
|
|
1393
|
+
checkAuthentication(params?: { autoRefresh: boolean }): Promise<boolean>; // Check the session, optionally refreshing tokens (never when serverSessionUri is set)
|
|
1394
|
+
login(params?: RedirectParams | PopupParams): Promise<void>; // Start login flow (redirect: `returnTo` sets where handleCallback() sends the user) (embedded/native: deprecated, returns a login flow instance - use `sdk.startSession()`)
|
|
1395
|
+
register(params?: RedirectParams | PopupParams): Promise<void>; // Start registration flow (same caveat as `login`)
|
|
1396
|
+
handleCallback(url?: string | URL): Promise<{ returnTo?: string }>; // Handle OAuth callback; resolves to the `returnTo` given to login()
|
|
1374
1397
|
logout(params?: LogoutParams): Promise<void>; // End session
|
|
1375
|
-
refresh(): Promise<void>; // Refresh access token
|
|
1398
|
+
refresh(params?: { returnTo?: string }): Promise<void>; // Refresh access token (server-managed: navigates to the server's refresh route, `${authUrlPrefix}/refresh`, instead; `returnTo` sets where it returns, default: the current URL)
|
|
1376
1399
|
revoke(): Promise<void>; // Revoke tokens
|
|
1377
|
-
|
|
1400
|
+
tokenExchange(params?: Record<string, string>): Promise<void>; // Perform a token exchange
|
|
1401
|
+
entry(url?: string | URL): Promise<EntryResponse>; // Handle external entry (embedded/native; resolves `{ session_id, short_app_id, language }`). Redirect/popup: `entry(url?, params?: RedirectOptions): Promise<void>`
|
|
1402
|
+
subscribeToEvent(eventName, callbackFn): { dispose: () => void }; // Subscribe to a single SDK event
|
|
1403
|
+
subscribeToAllEvents(callbackFn): { dispose: () => void }; // Subscribe to all SDK events
|
|
1378
1404
|
}
|
|
1379
1405
|
```
|
|
1380
1406
|
|
|
1407
|
+
##### During server-side rendering
|
|
1408
|
+
|
|
1409
|
+
The SDK instance only exists in the browser: a client-only plugin creates it when the app starts, and it is also available as `useNuxtApp().$strivacity`. During SSR, `useStrivacity()` returns a **read-only** context built from the current request's session (`useSession()`), so no state is ever shared between requests:
|
|
1410
|
+
|
|
1411
|
+
| Member | During SSR |
|
|
1412
|
+
| --- | --- |
|
|
1413
|
+
| `isAuthenticated`, `idTokenClaims`, `accessToken`, `accessTokenExpired`, `accessTokenExpirationDate` | Derived from `useSession()`. With client-managed sessions the server cannot see browser storage, so `isAuthenticated` is `false` |
|
|
1414
|
+
| `loading` | `false` with server-managed sessions, `true` with client-managed sessions (until the browser takes over) |
|
|
1415
|
+
| `refreshToken` | Always `null` |
|
|
1416
|
+
| `sdk.options`, `sdk.session` | Readable |
|
|
1417
|
+
| `checkAuthentication()`, `init()` | Resolve immediately |
|
|
1418
|
+
| `subscribeToEvent()`, `subscribeToAllEvents()` | No-ops (no events fire on the server) |
|
|
1419
|
+
| `login()`, `register()`, `logout()`, `refresh()`, `revoke()`, `handleCallback()`, `entry()`, `tokenExchange()` and the matching `sdk.*` methods | Throw: authentication flows only run in the browser. Call them from `onMounted()` or event handlers |
|
|
1420
|
+
|
|
1381
1421
|
#### useNativeLogin
|
|
1382
1422
|
|
|
1383
1423
|
Composable for managing native login flow state. Only available in `native` mode.
|
|
@@ -1399,10 +1439,10 @@ const ctx = useNativeLogin({
|
|
|
1399
1439
|
{
|
|
1400
1440
|
params?: NativeParams; // Initial flow parameters
|
|
1401
1441
|
onLogin?: (session: SessionData) => void | Promise<void>; // Called on successful login
|
|
1402
|
-
onClose?: () => void
|
|
1403
|
-
onError?: (error:
|
|
1404
|
-
onFallback?: (error: FallbackError) => void
|
|
1405
|
-
onGlobalMessage?: (message: NativeFlowMessage) => void
|
|
1442
|
+
onClose?: () => void | Promise<void>; // Called when user closes the flow
|
|
1443
|
+
onError?: (error: Error) => void | Promise<void>; // Called on error
|
|
1444
|
+
onFallback?: (error: FallbackError) => void | Promise<void>; // Called when fallback needed
|
|
1445
|
+
onGlobalMessage?: (message: NativeFlowMessage) => void | Promise<void>; // Called for global messages
|
|
1406
1446
|
}
|
|
1407
1447
|
```
|
|
1408
1448
|
|
|
@@ -1455,10 +1495,12 @@ export default defineEventHandler(async (event) => {
|
|
|
1455
1495
|
throw createError({ statusCode: 401 });
|
|
1456
1496
|
}
|
|
1457
1497
|
|
|
1458
|
-
return { idTokenClaims: session.
|
|
1498
|
+
return { idTokenClaims: session.claims };
|
|
1459
1499
|
});
|
|
1460
1500
|
```
|
|
1461
1501
|
|
|
1502
|
+
`sdk.getSession()` returns what the page-render middleware gets: with `autoRefresh` (the default) it refreshes an expired (or within `refreshSkew`) session first when a refresh token exists, at most once per request (later calls in the same request share the result), and resolves to `null` if the refresh fails. The default cookie storage writes the rotated cookie to the response directly; a custom storage that queues its `Set-Cookie` headers on the event needs them flushed (`flushSetCookies`). If you return the session itself to the browser, strip the refresh and ID tokens with `toClientSession(session)` (from `@strivacity/sdk-nuxt/utils`).
|
|
1503
|
+
|
|
1462
1504
|
> `useStrivacity(event)` throws if called on the client or without an `H3Event` - it's only available inside server routes, server plugins, and Nitro middleware.
|
|
1463
1505
|
|
|
1464
1506
|
<a id="server-storages"></a>
|
|
@@ -1469,7 +1511,7 @@ By default the Server SDK stores tokens encrypted in http-only cookies and login
|
|
|
1469
1511
|
#### Built-in session storages
|
|
1470
1512
|
|
|
1471
1513
|
- **`createEncryptedCookieStorage(secret, options?)`** - default storage that keeps the session encrypted in an http-only cookie.
|
|
1472
|
-
- **`createSessionIdCookieStorage(storage, options?)`** - puts only a small, random session-id cookie on the client and keeps the actual session payload in the `storage` you provide.
|
|
1514
|
+
- **`createSessionIdCookieStorage(storage, options?)`** - puts only a small, random session-id cookie on the client and keeps the actual session payload in the `storage` you provide. It supports back-channel logout when `storage` implements `deleteByLogoutToken`.
|
|
1473
1515
|
|
|
1474
1516
|
```ts
|
|
1475
1517
|
// server/storage.ts
|
|
@@ -1491,50 +1533,57 @@ export default defineNuxtConfig({
|
|
|
1491
1533
|
modules: ['@strivacity/sdk-nuxt'],
|
|
1492
1534
|
strivacity: {
|
|
1493
1535
|
// ...other options
|
|
1494
|
-
storageFactoryPath: '
|
|
1536
|
+
storageFactoryPath: '~~/server/storage', // default-exports the factory shown above
|
|
1495
1537
|
},
|
|
1496
1538
|
});
|
|
1497
1539
|
```
|
|
1498
1540
|
|
|
1499
1541
|
#### Custom storage
|
|
1500
1542
|
|
|
1501
|
-
For example you can use Redis via [unstorage](https://npmjs.com/package/unstorage)
|
|
1543
|
+
For example you can use Redis via [unstorage](https://npmjs.com/package/unstorage).
|
|
1544
|
+
|
|
1545
|
+
The SDK always reads and writes the session under the same key (`storageTokenName`), and passes the current H3 event as the last argument. A storage that ignores the event would therefore share a single session across all users, so key the data per browser session instead. The easiest way is to wrap your key-value store with `createSessionIdCookieStorage`, which puts a random session id in a cookie and calls your store with that id as the key:
|
|
1502
1546
|
|
|
1503
1547
|
```ts
|
|
1504
1548
|
// server/storage.ts
|
|
1505
1549
|
import { createStorage } from 'unstorage';
|
|
1506
1550
|
import redisDriver from 'unstorage/drivers/redis';
|
|
1507
|
-
import type {
|
|
1551
|
+
import type { ServerStorage } from '@strivacity/sdk-nuxt';
|
|
1552
|
+
import { createSessionIdCookieStorage } from '#imports';
|
|
1508
1553
|
|
|
1509
1554
|
const unstorageInstance = createStorage({ driver: redisDriver({ url: process.env.REDIS_URL }) });
|
|
1510
1555
|
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
}
|
|
1535
|
-
)
|
|
1536
|
-
|
|
1537
|
-
}
|
|
1556
|
+
// Session payload store - `key` is the per-browser session id provided by `createSessionIdCookieStorage`
|
|
1557
|
+
// (raw get/set keep the serialized session string as-is)
|
|
1558
|
+
const sessionStore: ServerStorage = {
|
|
1559
|
+
async get(key) {
|
|
1560
|
+
return unstorageInstance.getItemRaw<string>(`session:${key}`);
|
|
1561
|
+
},
|
|
1562
|
+
async set(key, value) {
|
|
1563
|
+
await unstorageInstance.setItemRaw(`session:${key}`, value);
|
|
1564
|
+
},
|
|
1565
|
+
async delete(key) {
|
|
1566
|
+
await unstorageInstance.removeItem(`session:${key}`);
|
|
1567
|
+
},
|
|
1568
|
+
// Required for back-channel logout support - see below.
|
|
1569
|
+
// Scans all stored sessions and removes those whose ID token claims match the logout token's sid or sub claim.
|
|
1570
|
+
async deleteByLogoutToken(logoutToken) {
|
|
1571
|
+
const keys = await unstorageInstance.getKeys('session');
|
|
1572
|
+
await Promise.all(
|
|
1573
|
+
keys.map(async (key) => {
|
|
1574
|
+
const raw = await unstorageInstance.getItemRaw<string>(key);
|
|
1575
|
+
if (!raw) return;
|
|
1576
|
+
const session = JSON.parse(raw);
|
|
1577
|
+
if ((logoutToken.sid && session.claims?.sid === logoutToken.sid) || (logoutToken.sub && session.claims?.sub === logoutToken.sub)) {
|
|
1578
|
+
await unstorageInstance.removeItem(key);
|
|
1579
|
+
}
|
|
1580
|
+
}),
|
|
1581
|
+
);
|
|
1582
|
+
},
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
export default function createStorageFactory() {
|
|
1586
|
+
return createSessionIdCookieStorage(sessionStore); // Custom Redis-backed session storage, keyed by a session-id cookie
|
|
1538
1587
|
}
|
|
1539
1588
|
```
|
|
1540
1589
|
|
|
@@ -1544,7 +1593,7 @@ export default defineNuxtConfig({
|
|
|
1544
1593
|
modules: ['@strivacity/sdk-nuxt'],
|
|
1545
1594
|
strivacity: {
|
|
1546
1595
|
// ...other options
|
|
1547
|
-
storageFactoryPath: '
|
|
1596
|
+
storageFactoryPath: '~~/server/storage', // default-exports the factory shown above
|
|
1548
1597
|
},
|
|
1549
1598
|
});
|
|
1550
1599
|
```
|
|
@@ -1555,9 +1604,9 @@ export default defineNuxtConfig({
|
|
|
1555
1604
|
|
|
1556
1605
|
OIDC back-channel logout lets the authorization server terminate sessions server-to-server, without involving the browser. When the IDP sends a logout event (e.g. an admin terminates a session, or the user logs out from a different device), it POSTs a signed `logout_token` JWT to `/auth/backchannel-logout` - already registered by the module - which routes it to `sdk.handleBackChannelLogout(event)`.
|
|
1557
1606
|
|
|
1558
|
-
The handler verifies the token's signature against the IDP's JWKS, validates the `iss`, `aud`, `iat` (freshness), and `jti` (replay protection) claims, requires the `http://schemas.openid.net/event/backchannel-logout` event and a `sid` or `sub` claim, then calls `storage.deleteByLogoutToken({ sid?, sub? })` to remove the matching session(s). It responds `200` on success, `400` for an invalid or malformed `logout_token`,
|
|
1607
|
+
The handler verifies the token's signature against the IDP's JWKS, validates the `iss`, `aud`, `iat` (freshness), and `jti` (replay protection) claims, requires the `http://schemas.openid.net/event/backchannel-logout` event and a `sid` or `sub` claim, then calls `storage.deleteByLogoutToken({ sid?, sub? })` to remove the matching session(s). It responds `200` on success, `400` for an invalid or malformed `logout_token`, `501` if the configured storage doesn't implement `deleteByLogoutToken`, and `500` if deleting the session fails.
|
|
1559
1608
|
|
|
1560
|
-
> **The default encrypted-cookie storage does not support back-channel logout** because each cookie is bound to a single browser session - there is no server-side index to look up by `sid` or `sub`. To support back-channel logout, use [`createSessionIdCookieStorage`](#server-storages) with a `storage` that implements `deleteByLogoutToken
|
|
1609
|
+
> **The default encrypted-cookie storage does not support back-channel logout** because each cookie is bound to a single browser session - there is no server-side index to look up by `sid` or `sub`. To support back-channel logout, use [`createSessionIdCookieStorage`](#server-storages) with a `storage` that implements `deleteByLogoutToken`, e.g. `createServerMemoryStorage()` for local testing or the Redis-backed store from the [Custom storage](#server-storages) example above.
|
|
1561
1610
|
|
|
1562
1611
|
Configure the **Back-channel logout URI** in your Strivacity application settings to:
|
|
1563
1612
|
|
|
@@ -1576,7 +1625,7 @@ For a complete explanation of the handshake and validation performed, see the co
|
|
|
1576
1625
|
options: NuxtServerSDKOptions; // resolved server SDK configuration
|
|
1577
1626
|
|
|
1578
1627
|
// Session management
|
|
1579
|
-
getSession(): Promise<SessionData | null>; // read the current session
|
|
1628
|
+
getSession(): Promise<SessionData | null>; // read the current session; with `autoRefresh` (default) it refreshes an expired (or within `refreshSkew`) one first, once per request; null if the refresh fails (what the SSR middleware uses)
|
|
1580
1629
|
updateSession(session): Promise<void>; // persist new session data
|
|
1581
1630
|
refreshSession(): Promise<SessionData>; // refresh tokens using the refresh token
|
|
1582
1631
|
revokeSession(): Promise<void>; // revoke tokens and clear the session
|
|
@@ -1584,20 +1633,20 @@ For a complete explanation of the handshake and validation performed, see the co
|
|
|
1584
1633
|
completeLogin(params): Promise<SessionData>; // exchange an authorization code for tokens
|
|
1585
1634
|
logout(postLogoutRedirectUri): Promise<URL>; // clear the session, returns the IDP end-session URL
|
|
1586
1635
|
|
|
1587
|
-
// Route handlers - each returns a Response; `handler` dispatches to the one matching the request path
|
|
1588
|
-
handleLogin(): Promise<Response>;
|
|
1589
|
-
handleRegister(): Promise<Response>;
|
|
1590
|
-
handleCallback(): Promise<Response>;
|
|
1591
|
-
handleRefresh(): Promise<Response>;
|
|
1592
|
-
handleRevoke(): Promise<Response>;
|
|
1593
|
-
handleEntry(): Promise<Response>;
|
|
1594
|
-
handleLogout(): Promise<Response>;
|
|
1595
|
-
handleBackChannelLogout(): Promise<Response>;
|
|
1596
|
-
handler(): Promise<Response>;
|
|
1636
|
+
// Route handlers - each takes the `H3Event` and returns a Response; `handler` dispatches to the one matching the request path
|
|
1637
|
+
handleLogin(event): Promise<Response>;
|
|
1638
|
+
handleRegister(event): Promise<Response>;
|
|
1639
|
+
handleCallback(event): Promise<Response>;
|
|
1640
|
+
handleRefresh(event): Promise<Response>;
|
|
1641
|
+
handleRevoke(event): Promise<Response>;
|
|
1642
|
+
handleEntry(event): Promise<Response>;
|
|
1643
|
+
handleLogout(event): Promise<Response>;
|
|
1644
|
+
handleBackChannelLogout(event): Promise<Response>;
|
|
1645
|
+
handler(event): Promise<Response | null>; // null if no auth route matched
|
|
1597
1646
|
}
|
|
1598
1647
|
```
|
|
1599
1648
|
|
|
1600
|
-
|
|
1649
|
+
The session-management methods already close over the current `H3Event` - there's no `event` parameter to pass at the call site. The route handlers (`handle*()` and `handler()`) take the event explicitly, e.g. `await sdk.handler(event)`.
|
|
1601
1650
|
|
|
1602
1651
|
### Server configuration reference
|
|
1603
1652
|
|
|
@@ -1610,27 +1659,44 @@ The Server SDK accepts the same configuration as the client SDK (see [Configurat
|
|
|
1610
1659
|
| `stateStorageFactoryPath` | `string` | No | In-memory `Map` | Path to a module default-exporting an `SDKStorage` factory for the OAuth2 state parameter |
|
|
1611
1660
|
| `loggingFactoryPath` | `string` | No | - | Path to a module default-exporting an `SDKLogging` factory |
|
|
1612
1661
|
| `httpClientFactoryPath` | `string` | No | - | Path to a module default-exporting an `SDKHttpClient` factory |
|
|
1613
|
-
| `authUrlPrefix` | `string` | No | `'/auth'` | URL prefix under which the module registers the auth routes |
|
|
1662
|
+
| `authUrlPrefix` | `string` | No | `'/auth'` | URL prefix under which the module registers the auth routes; with server-managed sessions `sdk.refresh()` and route guards send an expired session to `${authUrlPrefix}/refresh` |
|
|
1614
1663
|
| `serverSessionUri` | `string \| null` | No | `` `${authUrlPrefix}/login` `` | Enables server-managed sessions when set (the default); set to `null` to use client-managed sessions instead |
|
|
1615
|
-
| `postLoginRedirectUri` | `string` | No |
|
|
1616
|
-
| `postLogoutRedirectUri` | `string` | No |
|
|
1664
|
+
| `postLoginRedirectUri` | `string` | No | origin of `redirectUri` | Default redirect after login when no `?returnTo=` is given |
|
|
1665
|
+
| `postLogoutRedirectUri` | `string` | No | origin of `redirectUri` | Default redirect after logout |
|
|
1617
1666
|
| `cookieMaxAge` | `number` | No | `2592000` (30 days) | Max age of the session cookie in seconds |
|
|
1618
1667
|
|
|
1619
1668
|
---
|
|
1620
1669
|
|
|
1621
1670
|
### Route guards
|
|
1622
1671
|
|
|
1623
|
-
There's no client-side route guard composable in this SDK. Instead, add an opt-in Nuxt route middleware and apply it per-page
|
|
1672
|
+
There's no client-side route guard composable in this SDK. Instead, add an opt-in Nuxt route middleware and apply it per-page.
|
|
1673
|
+
|
|
1674
|
+
With server-managed sessions the browser never refreshes tokens itself, and the module's middleware only refreshes during SSR, so a session can expire between client-side navigations. The guard below sends an expired session through the Server SDK's refresh route (`sdk.refresh({ returnTo })`, a full-page navigation that comes back to the target page) and aborts the client-side navigation:
|
|
1624
1675
|
|
|
1625
1676
|
```ts
|
|
1626
1677
|
// app/middleware/auth.ts
|
|
1627
1678
|
export default defineNuxtRouteMiddleware(async (to) => {
|
|
1628
|
-
const sdk = useStrivacity();
|
|
1629
|
-
const authenticated = sdk.options.serverSessionUri ? !!useSession().value : await sdk.isAuthenticated;
|
|
1679
|
+
const { sdk } = useStrivacity();
|
|
1630
1680
|
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1681
|
+
// With client-managed sessions the session lives in browser storage, so only the browser can decide.
|
|
1682
|
+
if (import.meta.server && !sdk.options.serverSessionUri) {
|
|
1683
|
+
return;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
// Server-managed sessions, client-side navigation: send an expired session through the server's refresh route.
|
|
1687
|
+
// During SSR the module middleware already refreshed it.
|
|
1688
|
+
const session = useSession().value;
|
|
1689
|
+
|
|
1690
|
+
if (import.meta.client && sdk.options.serverSessionUri && session && isSessionExpired(session)) {
|
|
1691
|
+
await sdk.refresh({ returnTo: to.fullPath });
|
|
1692
|
+
return abortNavigation();
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
const isAuthenticated = sdk.options.serverSessionUri ? !!useSession().value : await sdk.isAuthenticated;
|
|
1696
|
+
|
|
1697
|
+
if (!isAuthenticated) {
|
|
1698
|
+
const returnToCookie = useCookie('sty.returnTo', { sameSite: 'lax', path: '/' });
|
|
1699
|
+
returnToCookie.value = to.path;
|
|
1634
1700
|
|
|
1635
1701
|
return navigateTo('/login');
|
|
1636
1702
|
}
|
|
@@ -1644,7 +1710,7 @@ definePageMeta({ middleware: ['auth'] });
|
|
|
1644
1710
|
</script>
|
|
1645
1711
|
```
|
|
1646
1712
|
|
|
1647
|
-
This is separate from the global session-hydration middleware the module registers
|
|
1713
|
+
This is separate from the global session-hydration middleware the module registers with server-managed sessions (see [Quick start](#quick-start)) - that one runs during SSR only and only seeds `useSession()` (refreshing a near-expiry session first, see [Quick start](#quick-start)), it never redirects. A failed refresh leaves `useSession()` `undefined`, so the guard above sends the user to log in. The guard above is what actually protects a page, and you choose which pages need it. To protect every page instead, name it `auth.global.ts` (and skip `/login` and other public routes inside it): the module registers its own middleware first, so `useSession()` is already filled when any app middleware runs, global ones included.
|
|
1648
1714
|
|
|
1649
1715
|
---
|
|
1650
1716
|
|
|
@@ -1672,7 +1738,11 @@ The client SDK accepts the same configuration as the core SDK - see the [core SD
|
|
|
1672
1738
|
|
|
1673
1739
|
### Migrating to v4.0
|
|
1674
1740
|
|
|
1675
|
-
v4 replaces the SDK's class-based flow architecture with function-based architecture, and unifies server-managed (BFF) session handling onto a shared Server SDK. `
|
|
1741
|
+
v4 replaces the SDK's class-based flow architecture with function-based architecture, and unifies server-managed (BFF) session handling onto a shared Server SDK. The `strivacity: {...}` key is still the only configuration, but `serverSessionUri` now defaults to server-managed sessions: add a `secret`, or set `serverSessionUri: null` to keep v3's client-managed behaviour. Custom storage and logging are referenced by file path (`storageFactoryPath`, `loggingFactoryPath`, ...). Apps need to update their code if they rendered `<StyLoginRenderer>` (replaced by `useNativeLogin()`), used `mode: 'custom'`, drove `native` mode through the old `NativeFlowHandler`, or call SDK methods during server-side rendering.
|
|
1742
|
+
|
|
1743
|
+
#### `useStrivacity()` is read-only during SSR
|
|
1744
|
+
|
|
1745
|
+
In v3 the SDK instance was a module-level singleton that was also created on the server, so concurrent requests shared it. In v4 the SDK instance only exists in the browser, and during SSR `useStrivacity()` returns a read-only context derived from the current request's session (see [During server-side rendering](#during-server-side-rendering)). Move calls such as `login()`, `logout()` or `handleCallback()` into `onMounted()` or event handlers.
|
|
1676
1746
|
|
|
1677
1747
|
#### Class-based flows replaced by functions
|
|
1678
1748
|
|
|
@@ -1699,7 +1769,7 @@ import type { SDKInitConfig, SDKOptions } from '@strivacity/sdk-core/types';
|
|
|
1699
1769
|
|
|
1700
1770
|
export function createCustomFlow(initConfig: SDKInitConfig) {
|
|
1701
1771
|
const state = getDefaultFlowState();
|
|
1702
|
-
const options = getSDKOptions<SDKOptions>(
|
|
1772
|
+
const options = getSDKOptions<SDKOptions>(initConfig);
|
|
1703
1773
|
const base = createBaseFlow(state, options);
|
|
1704
1774
|
|
|
1705
1775
|
async function refresh(): Promise<void> {
|
|
@@ -1722,7 +1792,7 @@ export default defineNuxtConfig({
|
|
|
1722
1792
|
modules: ['@strivacity/sdk-nuxt'],
|
|
1723
1793
|
strivacity: {
|
|
1724
1794
|
// ...
|
|
1725
|
-
serverSessionUri: '/auth/login', //
|
|
1795
|
+
serverSessionUri: '/auth/login', // set to `null` for client-managed sessions - omitting this line still defaults to server-managed
|
|
1726
1796
|
secret: process.env.SECRET,
|
|
1727
1797
|
},
|
|
1728
1798
|
});
|
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, resolvePath, addImportsDir, addServerImportsDir, addServerPlugin, addRouteMiddleware, addServerHandler } from '@nuxt/kit';
|
|
1
|
+
import { defineNuxtModule, createResolver, resolvePath, addPlugin, addImportsDir, addServerImportsDir, addServerPlugin, addRouteMiddleware, addServerHandler } from '@nuxt/kit';
|
|
2
2
|
|
|
3
3
|
const module$1 = defineNuxtModule({
|
|
4
4
|
meta: {
|
|
@@ -31,6 +31,7 @@ const module$1 = defineNuxtModule({
|
|
|
31
31
|
nuxt.options.nitro.alias["#strivacity-options-httpClient"] = httpClientPath;
|
|
32
32
|
nuxt.options.nitro.alias["#strivacity-options-storage"] = storagePath;
|
|
33
33
|
nuxt.options.nitro.alias["#strivacity-options-stateStorage"] = stateStoragePath;
|
|
34
|
+
addPlugin({ src: resolver.resolve("./runtime/plugins/strivacity.client"), mode: "client" });
|
|
34
35
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
35
36
|
addImportsDir(resolver.resolve("./runtime/storages"));
|
|
36
37
|
addImportsDir(resolver.resolve("./runtime/utils"));
|
|
@@ -39,7 +40,7 @@ const module$1 = defineNuxtModule({
|
|
|
39
40
|
addServerImportsDir(resolver.resolve("./runtime/server/utils"));
|
|
40
41
|
addServerImportsDir(resolver.resolve("./runtime/storages"));
|
|
41
42
|
addServerPlugin(resolver.resolve("./runtime/server/plugins/auth.server"));
|
|
42
|
-
addRouteMiddleware({ name: "strivacity", path: resolver.resolve("./runtime/middleware/auth.server"), global: true });
|
|
43
|
+
addRouteMiddleware({ name: "strivacity", path: resolver.resolve("./runtime/middleware/auth.server"), global: true }, { prepend: true });
|
|
43
44
|
addServerHandler({
|
|
44
45
|
method: "get",
|
|
45
46
|
route: `${options.authUrlPrefix}/login`,
|
|
@@ -76,9 +77,9 @@ const module$1 = defineNuxtModule({
|
|
|
76
77
|
handler: resolver.resolve("./runtime/server/api/auth/logout.get")
|
|
77
78
|
});
|
|
78
79
|
addServerHandler({
|
|
79
|
-
method: "
|
|
80
|
+
method: "post",
|
|
80
81
|
route: `${options.authUrlPrefix}/backchannel-logout`,
|
|
81
|
-
handler: resolver.resolve("./runtime/server/api/auth/backchannel-logout.
|
|
82
|
+
handler: resolver.resolve("./runtime/server/api/auth/backchannel-logout.post")
|
|
82
83
|
});
|
|
83
84
|
}
|
|
84
85
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strivacity/sdk-nuxt",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.2",
|
|
4
4
|
"description": "Strivacity Nuxt SDK client",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "strivacity <opensource@strivacity.com>",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@strivacity/sdk-core": "4.0.0-beta.
|
|
45
|
+
"@strivacity/sdk-core": "4.0.0-beta.2"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"nuxt": ">=4.0"
|
package/project.json
CHANGED
package/src/module.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
addServerHandler,
|
|
9
9
|
addServerPlugin,
|
|
10
10
|
addRouteMiddleware,
|
|
11
|
+
addPlugin,
|
|
11
12
|
} from '@nuxt/kit';
|
|
12
13
|
|
|
13
14
|
export type * from './runtime/types';
|
|
@@ -50,6 +51,7 @@ export default defineNuxtModule<NuxtServerSDKInitConfig>({
|
|
|
50
51
|
nuxt.options.nitro.alias['#strivacity-options-storage'] = storagePath;
|
|
51
52
|
nuxt.options.nitro.alias['#strivacity-options-stateStorage'] = stateStoragePath;
|
|
52
53
|
|
|
54
|
+
addPlugin({ src: resolver.resolve('./runtime/plugins/strivacity.client'), mode: 'client' });
|
|
53
55
|
addImportsDir(resolver.resolve('./runtime/composables'));
|
|
54
56
|
addImportsDir(resolver.resolve('./runtime/storages'));
|
|
55
57
|
addImportsDir(resolver.resolve('./runtime/utils'));
|
|
@@ -60,7 +62,9 @@ export default defineNuxtModule<NuxtServerSDKInitConfig>({
|
|
|
60
62
|
addServerImportsDir(resolver.resolve('./runtime/storages'));
|
|
61
63
|
|
|
62
64
|
addServerPlugin(resolver.resolve('./runtime/server/plugins/auth.server'));
|
|
63
|
-
|
|
65
|
+
// NOTE: prepend, so the session is loaded (and refreshed) before any app middleware runs - including global ones such as
|
|
66
|
+
// `app/middleware/auth.global.ts`, which Nuxt otherwise runs before module-registered middleware.
|
|
67
|
+
addRouteMiddleware({ name: 'strivacity', path: resolver.resolve('./runtime/middleware/auth.server'), global: true }, { prepend: true });
|
|
64
68
|
|
|
65
69
|
addServerHandler({
|
|
66
70
|
method: 'get',
|
|
@@ -98,9 +102,9 @@ export default defineNuxtModule<NuxtServerSDKInitConfig>({
|
|
|
98
102
|
handler: resolver.resolve('./runtime/server/api/auth/logout.get'),
|
|
99
103
|
});
|
|
100
104
|
addServerHandler({
|
|
101
|
-
method: '
|
|
105
|
+
method: 'post',
|
|
102
106
|
route: `${options.authUrlPrefix}/backchannel-logout`,
|
|
103
|
-
handler: resolver.resolve('./runtime/server/api/auth/backchannel-logout.
|
|
107
|
+
handler: resolver.resolve('./runtime/server/api/auth/backchannel-logout.post'),
|
|
104
108
|
});
|
|
105
109
|
}
|
|
106
110
|
},
|