nuxt-auth-utils 0.5.25 → 0.5.26

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.
Files changed (66) hide show
  1. package/README.md +28 -5
  2. package/dist/module.d.mts +3 -4
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +12 -4
  5. package/dist/runtime/app/components/AuthState.vue.d.ts +7 -6
  6. package/dist/runtime/server/api/session.get.d.ts +1 -5
  7. package/dist/runtime/server/lib/atproto/bluesky.d.ts +1 -1
  8. package/dist/runtime/server/lib/oauth/apple.d.ts +1 -1
  9. package/dist/runtime/server/lib/oauth/atlassian.d.ts +1 -1
  10. package/dist/runtime/server/lib/oauth/auth0.d.ts +1 -1
  11. package/dist/runtime/server/lib/oauth/authentik.d.ts +1 -1
  12. package/dist/runtime/server/lib/oauth/azureb2c.d.ts +1 -1
  13. package/dist/runtime/server/lib/oauth/azureb2c.js +0 -1
  14. package/dist/runtime/server/lib/oauth/battledotnet.d.ts +1 -1
  15. package/dist/runtime/server/lib/oauth/cognito.d.ts +1 -1
  16. package/dist/runtime/server/lib/oauth/discord.d.ts +1 -1
  17. package/dist/runtime/server/lib/oauth/dropbox.d.ts +1 -1
  18. package/dist/runtime/server/lib/oauth/facebook.d.ts +1 -1
  19. package/dist/runtime/server/lib/oauth/gitea.d.ts +1 -1
  20. package/dist/runtime/server/lib/oauth/github.d.ts +1 -1
  21. package/dist/runtime/server/lib/oauth/gitlab.d.ts +1 -1
  22. package/dist/runtime/server/lib/oauth/google.d.ts +1 -1
  23. package/dist/runtime/server/lib/oauth/heroku.d.ts +1 -1
  24. package/dist/runtime/server/lib/oauth/hubspot.d.ts +1 -1
  25. package/dist/runtime/server/lib/oauth/instagram.d.ts +1 -1
  26. package/dist/runtime/server/lib/oauth/keycloak.d.ts +1 -1
  27. package/dist/runtime/server/lib/oauth/kick.d.ts +1 -1
  28. package/dist/runtime/server/lib/oauth/line.d.ts +1 -1
  29. package/dist/runtime/server/lib/oauth/linear.d.ts +1 -1
  30. package/dist/runtime/server/lib/oauth/linkedin.d.ts +1 -1
  31. package/dist/runtime/server/lib/oauth/livechat.d.ts +2 -3
  32. package/dist/runtime/server/lib/oauth/livechat.js +1 -3
  33. package/dist/runtime/server/lib/oauth/microsoft.d.ts +1 -1
  34. package/dist/runtime/server/lib/oauth/okta.d.ts +1 -1
  35. package/dist/runtime/server/lib/oauth/ory.d.ts +1 -1
  36. package/dist/runtime/server/lib/oauth/ory.js +1 -1
  37. package/dist/runtime/server/lib/oauth/paypal.d.ts +1 -1
  38. package/dist/runtime/server/lib/oauth/polar.d.ts +1 -1
  39. package/dist/runtime/server/lib/oauth/roblox.d.ts +1 -1
  40. package/dist/runtime/server/lib/oauth/salesforce.d.ts +1 -1
  41. package/dist/runtime/server/lib/oauth/seznam.d.ts +1 -1
  42. package/dist/runtime/server/lib/oauth/shopifyCustomer.d.ts +26 -0
  43. package/dist/runtime/server/lib/oauth/shopifyCustomer.js +90 -0
  44. package/dist/runtime/server/lib/oauth/slack.d.ts +1 -1
  45. package/dist/runtime/server/lib/oauth/spotify.d.ts +1 -1
  46. package/dist/runtime/server/lib/oauth/steam.d.ts +1 -1
  47. package/dist/runtime/server/lib/oauth/steam.js +2 -1
  48. package/dist/runtime/server/lib/oauth/strava.d.ts +1 -1
  49. package/dist/runtime/server/lib/oauth/tiktok.d.ts +1 -1
  50. package/dist/runtime/server/lib/oauth/twitch.d.ts +1 -1
  51. package/dist/runtime/server/lib/oauth/vk.d.ts +1 -1
  52. package/dist/runtime/server/lib/oauth/workos.d.ts +1 -1
  53. package/dist/runtime/server/lib/oauth/x.d.ts +1 -1
  54. package/dist/runtime/server/lib/oauth/xsuaa.d.ts +1 -1
  55. package/dist/runtime/server/lib/oauth/yandex.d.ts +1 -1
  56. package/dist/runtime/server/lib/oauth/zitadel.d.ts +1 -1
  57. package/dist/runtime/server/lib/oauth/zitadel.js +5 -4
  58. package/dist/runtime/server/lib/utils.d.ts +8 -8
  59. package/dist/runtime/server/lib/utils.js +36 -20
  60. package/dist/runtime/server/plugins/oauth.d.ts +1 -1
  61. package/dist/runtime/server/utils/password.d.ts +17 -0
  62. package/dist/runtime/server/utils/password.js +3 -0
  63. package/dist/runtime/server/utils/session.d.ts +3 -2
  64. package/dist/runtime/types/oauth-config.d.ts +1 -1
  65. package/dist/runtime/types/utils.d.ts +14 -0
  66. package/package.json +17 -17
package/README.md CHANGED
@@ -156,11 +156,8 @@ const session = await requireUserSession(event)
156
156
 
157
157
  You can define the type for your user session by creating a type declaration file (for example, `auth.d.ts`) in your project to augment the `UserSession` type:
158
158
 
159
- > [!NOTE]
160
- > If you are using Nuxt >=4.0.0 or compatibility version 4 add the `auth.d.ts` file to the `shared` directory to get the correct types in server and client.
161
-
162
159
  ```ts
163
- // auth.d.ts
160
+ // shared/types/auth.d.ts
164
161
  declare module '#auth-utils' {
165
162
  interface User {
166
163
  // Add your own fields
@@ -245,6 +242,7 @@ It can also be set using environment variables:
245
242
  - Polar
246
243
  - Salesforce
247
244
  - Seznam
245
+ - Shopify Customer
248
246
  - Slack
249
247
  - Spotify
250
248
  - Steam
@@ -301,6 +299,17 @@ if (await verifyPassword(hashedPassword, 'user_password')) {
301
299
  }
302
300
  ```
303
301
 
302
+ It also provides a `passwordNeedsRehash` function to check if a password needs to be rehashed. This is useful when the hash settings are changed, such as as increasing the scrypt cost parameters.
303
+
304
+ ```ts
305
+ const needsRehash = await passwordNeedsRehash(hashedPassword)
306
+
307
+ if (needsRehash) {
308
+ // Password needs to be rehashed
309
+ hashedPassword = await hashPassword('user_password')
310
+ }
311
+ ```
312
+
304
313
  You can configure the scrypt options in your `nuxt.config.ts`:
305
314
 
306
315
  ```ts
@@ -600,7 +609,7 @@ This is because the user session is stored in a secure cookie and cannot be acce
600
609
 
601
610
  **This means that you should not rely on the user session during prerendering.**
602
611
 
603
- You may also choose to instruct Nuxt AUth Utils to fetch the user session only on the client side, with the `loadStrategy` option in your `nuxt.config.ts`:
612
+ You may also choose to instruct Nuxt Auth Utils to fetch the user session only on the client side, with the `loadStrategy` option in your `nuxt.config.ts`:
604
613
 
605
614
  ```ts
606
615
  export default defineNuxtConfig({
@@ -612,6 +621,20 @@ export default defineNuxtConfig({
612
621
 
613
622
  When using the `client-only` load strategy, the user session can still be manually fetched on the server side by calling `fetch` from the `useUserSession` composable.
614
623
 
624
+ ### Disable session loading
625
+
626
+ You may also choose to disable session loading entirely, with the `loadStrategy` option in your `nuxt.config.ts`:
627
+
628
+ ```ts
629
+ export default defineNuxtConfig({
630
+ auth: {
631
+ loadStrategy: 'none'
632
+ }
633
+ })
634
+ ```
635
+
636
+ When using the `none` load strategy, the user session can still be manually fetched by calling `useUserSession().fetch()`.
637
+
615
638
  ### `<AuthState>` component
616
639
 
617
640
  You can use the `<AuthState>` component to safely display auth-related data in your components without worrying about the rendering mode.
package/dist/module.d.mts CHANGED
@@ -1,4 +1,3 @@
1
- import * as _nuxt_schema from '@nuxt/schema';
2
1
  import { ScryptConfig } from '@adonisjs/hash/types';
3
2
  import { SessionConfig } from 'h3';
4
3
 
@@ -26,7 +25,7 @@ interface ModuleOptions {
26
25
  * Session load strategy
27
26
  * @default 'server-first'
28
27
  */
29
- loadStrategy?: 'server-first' | 'client-only';
28
+ loadStrategy?: 'server-first' | 'client-only' | 'none';
30
29
  }
31
30
  declare module 'nuxt/schema' {
32
31
  interface RuntimeConfig {
@@ -40,11 +39,11 @@ declare module 'nuxt/schema' {
40
39
  }
41
40
  interface PublicRuntimeConfig {
42
41
  auth: {
43
- loadStrategy: 'server-first' | 'client-only';
42
+ loadStrategy: 'server-first' | 'client-only' | 'none';
44
43
  };
45
44
  }
46
45
  }
47
- declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
46
+ declare const _default: any;
48
47
 
49
48
  export { _default as default };
50
49
  export type { ModuleOptions };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "auth-utils",
3
3
  "configKey": "auth",
4
- "version": "0.5.25",
4
+ "version": "0.5.26",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -5,7 +5,7 @@ import { defu } from 'defu';
5
5
  import { randomUUID } from 'uncrypto';
6
6
  import { atprotoProviders, atprotoProviderDefaultClientMetadata, getClientMetadataFilename } from '../dist/runtime/utils/atproto.js';
7
7
 
8
- const module = defineNuxtModule({
8
+ const module$1 = defineNuxtModule({
9
9
  meta: {
10
10
  name: "auth-utils",
11
11
  configKey: "auth"
@@ -32,8 +32,10 @@ const module = defineNuxtModule({
32
32
  }
33
33
  addComponentsDir({ path: resolver.resolve("./runtime/app/components") });
34
34
  addImports(composables);
35
- addPlugin(resolver.resolve("./runtime/app/plugins/session.server"));
36
- addPlugin(resolver.resolve("./runtime/app/plugins/session.client"));
35
+ if (options.loadStrategy !== "none") {
36
+ addPlugin(resolver.resolve("./runtime/app/plugins/session.server"));
37
+ addPlugin(resolver.resolve("./runtime/app/plugins/session.client"));
38
+ }
37
39
  addServerPlugin(resolver.resolve("./runtime/server/plugins/oauth"));
38
40
  addServerImportsDir(resolver.resolve("./runtime/server/lib/oauth"));
39
41
  if (nuxt.options.nitro?.experimental?.websocket) {
@@ -385,7 +387,13 @@ const module = defineNuxtModule({
385
387
  tokenURL: "",
386
388
  userURL: ""
387
389
  });
390
+ runtimeConfig.oauth.shopifyCustomer = defu(runtimeConfig.oauth.shopifyCustomer, {
391
+ shopDomain: "",
392
+ clientId: "",
393
+ redirectURL: "",
394
+ scope: []
395
+ });
388
396
  }
389
397
  });
390
398
 
391
- export { module as default };
399
+ export { module$1 as default };
@@ -1,16 +1,17 @@
1
1
  declare var __VLS_1: {
2
- loggedIn: boolean;
3
- user: import("../../types/index.js").User | null;
4
- session: import("../../types/index.js").UserSession | null;
5
- clear: () => Promise<void>;
2
+ loggedIn: any;
3
+ user: any;
4
+ session: any;
5
+ clear: any;
6
6
  }, __VLS_3: {};
7
7
  type __VLS_Slots = {} & {
8
8
  default?: (props: typeof __VLS_1) => any;
9
9
  } & {
10
10
  placeholder?: (props: typeof __VLS_3) => any;
11
11
  };
12
- declare const __VLS_component: import("vue-demi").DefineComponent<{}, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {}, string, import("vue-demi").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, true, {}, any>;
13
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
12
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
14
15
  export default _default;
15
16
  type __VLS_WithSlots<T, S> = T & {
16
17
  new (): {
@@ -1,6 +1,2 @@
1
- declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
- [key: string]: unknown;
3
- id: string;
4
- user?: import("../../types/index.js").User;
5
- }>>;
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<UserSession>>;
6
2
  export default _default;
@@ -22,7 +22,7 @@ type BlueSkyTokens = NodeSavedSession['tokenSet'];
22
22
  export declare function defineOAuthBlueskyEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBlueskyConfig, {
23
23
  user: BlueSkyUser;
24
24
  tokens: BlueSkyTokens;
25
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
25
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
26
26
  export declare class StateStore implements NodeSavedStateStore {
27
27
  private event;
28
28
  private readonly stateKey;
@@ -74,4 +74,4 @@ export declare function defineOAuthAppleEventHandler({ config, onSuccess, onErro
74
74
  user: OAuthAppleUser;
75
75
  payload: OAuthAppleTokens;
76
76
  tokens: any;
77
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
77
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -91,5 +91,5 @@ export interface OAuthAtlassianConfig {
91
91
  export declare function defineOAuthAtlassianEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthAtlassianConfig, {
92
92
  user: AtlassianUser;
93
93
  tokens: AtlassianTokens;
94
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
94
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
95
95
  export {};
@@ -57,4 +57,4 @@ export interface OAuthAuth0Config {
57
57
  */
58
58
  redirectURL?: string;
59
59
  }
60
- export declare function defineOAuthAuth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
60
+ export declare function defineOAuthAuth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -27,4 +27,4 @@ export interface OAuthAuthentikConfig {
27
27
  */
28
28
  scope?: string[];
29
29
  }
30
- export declare function defineOAuthAuthentikEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuthentikConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
30
+ export declare function defineOAuthAuthentikEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuthentikConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -51,4 +51,4 @@ export interface OAuthAzureB2CConfig {
51
51
  */
52
52
  redirectURL?: string;
53
53
  }
54
- export declare function defineOAuthAzureB2CEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAzureB2CConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
54
+ export declare function defineOAuthAzureB2CEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAzureB2CConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -37,7 +37,6 @@ export function defineOAuthAzureB2CEventHandler({ config, onSuccess, onError })
37
37
  if (query.state !== state) {
38
38
  return handleInvalidState(event, "azureb2c", onError);
39
39
  }
40
- console.info("code verifier", verifier.code_verifier);
41
40
  const tokens = await requestAccessToken(tokenURL, {
42
41
  body: {
43
42
  grant_type: "authorization_code",
@@ -45,4 +45,4 @@ export interface OAuthBattledotnetConfig {
45
45
  */
46
46
  redirectURL?: string;
47
47
  }
48
- export declare function defineOAuthBattledotnetEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBattledotnetConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
48
+ export declare function defineOAuthBattledotnetEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBattledotnetConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -36,4 +36,4 @@ export interface OAuthCognitoConfig {
36
36
  */
37
37
  redirectURL?: string;
38
38
  }
39
- export declare function defineOAuthCognitoEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthCognitoConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
39
+ export declare function defineOAuthCognitoEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthCognitoConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -50,4 +50,4 @@ export interface OAuthDiscordConfig {
50
50
  */
51
51
  redirectURL?: string;
52
52
  }
53
- export declare function defineOAuthDiscordEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDiscordConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
53
+ export declare function defineOAuthDiscordEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDiscordConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -44,4 +44,4 @@ export interface OAuthDropboxConfig {
44
44
  */
45
45
  redirectURL?: string;
46
46
  }
47
- export declare function defineOAuthDropboxEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDropboxConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
47
+ export declare function defineOAuthDropboxEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDropboxConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -45,4 +45,4 @@ export interface OAuthFacebookConfig {
45
45
  */
46
46
  redirectURL?: string;
47
47
  }
48
- export declare function defineOAuthFacebookEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthFacebookConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
48
+ export declare function defineOAuthFacebookEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthFacebookConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -48,4 +48,4 @@ export interface OAuthGiteaConfig {
48
48
  */
49
49
  baseURL?: string;
50
50
  }
51
- export declare function defineOAuthGiteaEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGiteaConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
51
+ export declare function defineOAuthGiteaEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGiteaConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -93,5 +93,5 @@ interface GitHubTokens {
93
93
  export declare function defineOAuthGitHubEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthGitHubConfig, {
94
94
  user: GitHubUser;
95
95
  tokens: GitHubTokens;
96
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
96
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
97
97
  export {};
@@ -49,4 +49,4 @@ export interface OAuthGitLabConfig {
49
49
  */
50
50
  baseURL?: string;
51
51
  }
52
- export declare function defineOAuthGitLabEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGitLabConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
52
+ export declare function defineOAuthGitLabEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGitLabConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -44,4 +44,4 @@ export interface OAuthGoogleConfig {
44
44
  */
45
45
  redirectURL?: string;
46
46
  }
47
- export declare function defineOAuthGoogleEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGoogleConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
47
+ export declare function defineOAuthGoogleEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGoogleConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -38,4 +38,4 @@ export interface OAuthHerokuConfig {
38
38
  */
39
39
  redirectURL?: string;
40
40
  }
41
- export declare function defineOAuthHerokuEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthHerokuConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
41
+ export declare function defineOAuthHerokuEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthHerokuConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -23,4 +23,4 @@ export interface OAuthHubspotConfig {
23
23
  */
24
24
  scope?: string[];
25
25
  }
26
- export declare function defineOAuthHubspotEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthHubspotConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
26
+ export declare function defineOAuthHubspotEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthHubspotConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -45,4 +45,4 @@ export interface OAuthInstagramConfig {
45
45
  */
46
46
  redirectURL?: string;
47
47
  }
48
- export declare function defineOAuthInstagramEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthInstagramConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
48
+ export declare function defineOAuthInstagramEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthInstagramConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -45,4 +45,4 @@ export interface OAuthKeycloakConfig {
45
45
  */
46
46
  redirectURL?: string;
47
47
  }
48
- export declare function defineOAuthKeycloakEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthKeycloakConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
48
+ export declare function defineOAuthKeycloakEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthKeycloakConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -35,4 +35,4 @@ export interface OAuthKickConfig {
35
35
  */
36
36
  redirectURL?: string;
37
37
  }
38
- export declare function defineOAuthKickEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthKickConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
38
+ export declare function defineOAuthKickEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthKickConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -42,4 +42,4 @@ export interface OAuthLineConfig {
42
42
  */
43
43
  redirectURL?: string;
44
44
  }
45
- export declare function defineOAuthLineEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthLineConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
45
+ export declare function defineOAuthLineEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthLineConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -38,4 +38,4 @@ export interface OAuthLinearConfig {
38
38
  */
39
39
  redirectURL?: string;
40
40
  }
41
- export declare function defineOAuthLinearEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthLinearConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
41
+ export declare function defineOAuthLinearEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthLinearConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -42,4 +42,4 @@ export interface OAuthLinkedInConfig {
42
42
  */
43
43
  redirectURL?: string;
44
44
  }
45
- export declare function defineOAuthLinkedInEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthLinkedInConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
45
+ export declare function defineOAuthLinkedInEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthLinkedInConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -60,8 +60,7 @@ export interface LiveChatConfig {
60
60
  */
61
61
  userURL?: string;
62
62
  /**
63
- * LiveChat OAuth Scope. accounts--my:ro is always applied to get user profile.
64
- * @default ['accounts--my:ro']
63
+ * LiveChat OAuth Scope. If not provided, the default scope from LiveChat will be used.
65
64
  * @example ['accounts--my:ro', 'chats--my:ro']
66
65
  */
67
66
  scope?: string[];
@@ -71,4 +70,4 @@ export interface LiveChatConfig {
71
70
  */
72
71
  authorizationParams?: Record<string, string>;
73
72
  }
74
- export declare function defineOAuthLiveChatEventHandler({ config, onSuccess, onError, }: OAuthConfig<LiveChatConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
73
+ export declare function defineOAuthLiveChatEventHandler({ config, onSuccess, onError, }: OAuthConfig<LiveChatConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -19,7 +19,6 @@ export function defineOAuthLiveChatEventHandler({
19
19
  authorizationURL: "https://accounts.livechat.com",
20
20
  tokenURL: "https://accounts.livechat.com/v2/token",
21
21
  userURL: "https://accounts.livechat.com/v2/accounts/me",
22
- scope: [],
23
22
  authorizationParams: {
24
23
  state: randomUUID()
25
24
  }
@@ -34,7 +33,6 @@ export function defineOAuthLiveChatEventHandler({
34
33
  }
35
34
  const query = getQuery(event);
36
35
  const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
37
- const scope = [.../* @__PURE__ */ new Set([...config.scope, "accounts--my:ro"])].join(" ");
38
36
  if (!query.code) {
39
37
  return sendRedirect(
40
38
  event,
@@ -42,7 +40,7 @@ export function defineOAuthLiveChatEventHandler({
42
40
  client_id: config.clientId,
43
41
  redirect_uri: redirectURL,
44
42
  response_type: "code",
45
- scope,
43
+ scope: config.scope?.length ? config.scope.join(" ") : void 0,
46
44
  ...config.authorizationParams
47
45
  })
48
46
  );
@@ -51,4 +51,4 @@ export interface OAuthMicrosoftConfig {
51
51
  */
52
52
  redirectURL?: string;
53
53
  }
54
- export declare function defineOAuthMicrosoftEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthMicrosoftConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
54
+ export declare function defineOAuthMicrosoftEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthMicrosoftConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -85,4 +85,4 @@ export interface OAuthOktaConfig {
85
85
  */
86
86
  openIdConfigCacheTTL?: number;
87
87
  }
88
- export declare function defineOAuthOktaEventHandler({ config, onSuccess, onError }: OAuthConfigExt<OAuthOktaConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
88
+ export declare function defineOAuthOktaEventHandler({ config, onSuccess, onError }: OAuthConfigExt<OAuthOktaConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -48,4 +48,4 @@ export interface OAuthOryConfig {
48
48
  */
49
49
  userURL?: string;
50
50
  }
51
- export declare function defineOAuthOryEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthOryConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
51
+ export declare function defineOAuthOryEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthOryConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -57,7 +57,7 @@ export function defineOAuthOryEventHandler({ config, onSuccess, onError }) {
57
57
  );
58
58
  }
59
59
  if (query.state !== state) {
60
- handleInvalidState(event, "ory", onError);
60
+ return handleInvalidState(event, "ory", onError);
61
61
  }
62
62
  const tokenURL = `${config.sdkURL}${config.tokenURL}`;
63
63
  const tokens = await requestAccessToken(tokenURL, {
@@ -49,4 +49,4 @@ export interface OAuthPaypalConfig {
49
49
  */
50
50
  redirectURL?: string;
51
51
  }
52
- export declare function defineOAuthPaypalEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthPaypalConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
52
+ export declare function defineOAuthPaypalEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthPaypalConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -46,4 +46,4 @@ export interface OAuthPolarConfig {
46
46
  */
47
47
  redirectURL?: string;
48
48
  }
49
- export declare function defineOAuthPolarEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthPolarConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
49
+ export declare function defineOAuthPolarEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthPolarConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -123,4 +123,4 @@ export interface OAuthRobloxUser {
123
123
  visibility: 'SOCIAL_NETWORK_VISIBILITY_UNSPECIFIED' | 'NO_ONE' | 'FRIENDS' | 'FRIENDS_AND_FOLLOWING' | 'FRIENDS_FOLLOWING_AND_FOLLOWERS' | 'EVERYONE';
124
124
  };
125
125
  }
126
- export declare function defineOAuthRobloxEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthRobloxConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
126
+ export declare function defineOAuthRobloxEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthRobloxConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -43,4 +43,4 @@ export interface OAuthSalesforceConfig {
43
43
  */
44
44
  redirectURL?: string;
45
45
  }
46
- export declare function defineOAuthSalesforceEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthSalesforceConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
46
+ export declare function defineOAuthSalesforceEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthSalesforceConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -95,4 +95,4 @@ export interface OAuthSeznamUser {
95
95
  export declare function defineOAuthSeznamEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSeznamConfig, {
96
96
  user: OAuthSeznamUser;
97
97
  tokens: unknown;
98
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
98
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -0,0 +1,26 @@
1
+ import type { OAuthConfig } from '#auth-utils';
2
+ export interface OAuthShopifyCustomerConfig {
3
+ /**
4
+ * Shopify shop domain ID
5
+ * @default process.env.NUXT_OAUTH_SHOPIFY_CUSTOMER_SHOP_DOMAIN
6
+ * @example 123.myshopify.com
7
+ */
8
+ shopDomain?: string;
9
+ /**
10
+ * Shopify Customer Client ID
11
+ * @default process.env.NUXT_OAUTH_SHOPIFY_CUSTOMER_CLIENT_ID
12
+ */
13
+ clientId?: string;
14
+ /**
15
+ * Shopify Customer OAuth Scope
16
+ * @default ['openid', 'email', 'customer-account-api:full']
17
+ * @example ['openid', 'email', 'customer-account-api:full']
18
+ */
19
+ scope?: string[];
20
+ /**
21
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
22
+ * @default process.env.NUXT_OAUTH_SHOPIFY_CUSTOMER_REDIRECT_URL or current URL
23
+ */
24
+ redirectURL?: string;
25
+ }
26
+ export declare function defineOAuthShopifyCustomerEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthShopifyCustomerConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -0,0 +1,90 @@
1
+ import { createError, eventHandler, getQuery, sendRedirect } from "h3";
2
+ import { withQuery } from "ufo";
3
+ import { defu } from "defu";
4
+ import { getOAuthRedirectURL, handleAccessTokenErrorResponse, handleMissingConfiguration, handlePkceVerifier, handleState, requestAccessToken } from "../utils.js";
5
+ import { useRuntimeConfig } from "#imports";
6
+ export function defineOAuthShopifyCustomerEventHandler({
7
+ config,
8
+ onSuccess,
9
+ onError
10
+ }) {
11
+ return eventHandler(async (event) => {
12
+ config = defu(config, useRuntimeConfig(event).oauth?.shopifyCustomer, {});
13
+ const query = getQuery(event);
14
+ if (!config.clientId || !config.shopDomain) {
15
+ return handleMissingConfiguration(event, "spotify", ["clientId", "shopDomain"], onError);
16
+ }
17
+ const verifier = await handlePkceVerifier(event);
18
+ const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
19
+ const discoveryResponse = await $fetch(`https://${config.shopDomain}/.well-known/openid-configuration`).then((d) => d).catch(() => null);
20
+ if (!discoveryResponse?.issuer) {
21
+ const error = createError({
22
+ statusCode: 400,
23
+ message: "Getting Shopify discovery endpoint failed."
24
+ });
25
+ if (!onError) throw error;
26
+ return onError(event, error);
27
+ }
28
+ const state = await handleState(event);
29
+ if (!query.code) {
30
+ config.scope = config.scope && config.scope.length > 0 ? config.scope : ["openid", "email", "customer-account-api:full"];
31
+ config.scope = [...new Set(config.scope)];
32
+ return sendRedirect(
33
+ event,
34
+ withQuery(discoveryResponse.authorization_endpoint, {
35
+ response_type: "code",
36
+ client_id: config.clientId,
37
+ redirect_uri: redirectURL,
38
+ scope: config.scope.join(" "),
39
+ state,
40
+ code_challenge: verifier.code_challenge,
41
+ code_challenge_method: verifier.code_challenge_method
42
+ })
43
+ );
44
+ }
45
+ const tokens = await requestAccessToken(discoveryResponse.token_endpoint, {
46
+ body: {
47
+ grant_type: "authorization_code",
48
+ client_id: config.clientId,
49
+ redirect_uri: redirectURL,
50
+ code: query.code,
51
+ code_verifier: verifier.code_verifier
52
+ }
53
+ }).catch(() => ({ error: "failed" }));
54
+ if (tokens.error) {
55
+ return handleAccessTokenErrorResponse(event, "shopifyCustomer", tokens, onError);
56
+ }
57
+ const apiDiscoveryUrl = await $fetch(`https://${config.shopDomain}/.well-known/customer-account-api`).then((d) => d).catch(() => null);
58
+ if (!apiDiscoveryUrl?.graphql_api) {
59
+ const error = createError({
60
+ statusCode: 400,
61
+ message: "Getting Shopify api endpoints failed."
62
+ });
63
+ if (!onError) throw error;
64
+ return onError(event, error);
65
+ }
66
+ const user = await $fetch(apiDiscoveryUrl.graphql_api, {
67
+ method: "POST",
68
+ headers: {
69
+ "Content-Type": "application/json",
70
+ "Authorization": tokens.access_token
71
+ },
72
+ body: JSON.stringify({
73
+ operationName: "getCustomer",
74
+ query: "query { customer { firstName lastName emailAddress { emailAddress }}}"
75
+ })
76
+ }).then((d) => d.data).catch(() => null);
77
+ if (!user || !user.customer) {
78
+ const error = createError({
79
+ statusCode: 400,
80
+ message: "Getting Shopify Customer failed."
81
+ });
82
+ if (!onError) throw error;
83
+ return onError(event, error);
84
+ }
85
+ return onSuccess(event, {
86
+ tokens,
87
+ user: user.customer
88
+ });
89
+ });
90
+ }
@@ -38,4 +38,4 @@ export interface OAuthSlackConfig {
38
38
  */
39
39
  redirectURL?: string;
40
40
  }
41
- export declare function defineOAuthSlackEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthSlackConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
41
+ export declare function defineOAuthSlackEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthSlackConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -44,4 +44,4 @@ export interface OAuthSpotifyConfig {
44
44
  */
45
45
  redirectURL?: string;
46
46
  }
47
- export declare function defineOAuthSpotifyEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSpotifyConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
47
+ export declare function defineOAuthSpotifyEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSpotifyConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -17,4 +17,4 @@ export interface OAuthSteamConfig {
17
17
  */
18
18
  redirectURL?: string;
19
19
  }
20
- export declare function defineOAuthSteamEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSteamConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
20
+ export declare function defineOAuthSteamEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSteamConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -15,11 +15,12 @@ export function defineOAuthSteamEventHandler({ config, onSuccess, onError }) {
15
15
  const url = getRequestURL(event);
16
16
  if (!query["openid.claimed_id"]) {
17
17
  const redirectURL = config.redirectURL || getRequestURL(event).href;
18
+ const realm = url.port ? `${url.protocol}//${url.hostname}:${url.port}` : `${url.protocol}//${url.hostname}`;
18
19
  const steamOpenIdParams = {
19
20
  "openid.ns": "http://specs.openid.net/auth/2.0",
20
21
  "openid.mode": "checkid_setup",
21
22
  "openid.return_to": redirectURL,
22
- "openid.realm": `${url.protocol}//${url.hostname}`,
23
+ "openid.realm": realm,
23
24
  "openid.identity": "http://specs.openid.net/auth/2.0/identifier_select",
24
25
  "openid.claimed_id": "http://specs.openid.net/auth/2.0/identifier_select"
25
26
  };
@@ -116,4 +116,4 @@ export interface OAuthStravaTokens {
116
116
  export declare function defineOAuthStravaEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthStravaConfig, {
117
117
  user: OAuthStravaUser;
118
118
  tokens: OAuthStravaTokens;
119
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
119
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -42,4 +42,4 @@ export interface OAuthTikTokConfig {
42
42
  */
43
43
  redirectURL?: string;
44
44
  }
45
- export declare function defineOAuthTikTokEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTikTokConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
45
+ export declare function defineOAuthTikTokEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTikTokConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -44,4 +44,4 @@ export interface OAuthTwitchConfig {
44
44
  */
45
45
  redirectURL?: string;
46
46
  }
47
- export declare function defineOAuthTwitchEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTwitchConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
47
+ export declare function defineOAuthTwitchEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTwitchConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -43,4 +43,4 @@ export interface OAuthVKConfig {
43
43
  */
44
44
  redirectURL?: string;
45
45
  }
46
- export declare function defineOAuthVKEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthVKConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
46
+ export declare function defineOAuthVKEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthVKConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -63,4 +63,4 @@ export interface OAuthWorkOSTokens {
63
63
  export declare function defineOAuthWorkOSEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthWorkOSConfig, {
64
64
  user: OAuthWorkOSUser;
65
65
  tokens: OAuthWorkOSTokens;
66
- }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
66
+ }>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -43,4 +43,4 @@ export interface OAuthXConfig {
43
43
  */
44
44
  redirectURL?: string;
45
45
  }
46
- export declare function defineOAuthXEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthXConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
46
+ export declare function defineOAuthXEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthXConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -28,4 +28,4 @@ export interface OAuthXSUAAConfig {
28
28
  */
29
29
  redirectURL?: string;
30
30
  }
31
- export declare function defineOAuthXSUAAEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthXSUAAConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
31
+ export declare function defineOAuthXSUAAEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthXSUAAConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -43,4 +43,4 @@ export interface OAuthYandexConfig {
43
43
  */
44
44
  redirectURL?: string;
45
45
  }
46
- export declare function defineOAuthYandexEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthYandexConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
46
+ export declare function defineOAuthYandexEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthYandexConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -34,4 +34,4 @@ export interface OAuthZitadelConfig {
34
34
  */
35
35
  redirectURL?: string;
36
36
  }
37
- export declare function defineOAuthZitadelEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthZitadelConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
37
+ export declare function defineOAuthZitadelEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthZitadelConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
@@ -1,5 +1,5 @@
1
1
  import { eventHandler, getQuery, sendRedirect } from "h3";
2
- import { withQuery } from "ufo";
2
+ import { hasProtocol, withQuery } from "ufo";
3
3
  import { defu } from "defu";
4
4
  import { handleMissingConfiguration, handleAccessTokenErrorResponse, getOAuthRedirectURL, requestAccessToken, handleState, handlePkceVerifier, handleInvalidState } from "../utils.js";
5
5
  import { useRuntimeConfig, createError } from "#imports";
@@ -21,8 +21,9 @@ export function defineOAuthZitadelEventHandler({ config, onSuccess, onError }) {
21
21
  if (!config.clientId || !config.domain) {
22
22
  return handleMissingConfiguration(event, "zitadel", ["clientId", "domain"], onError);
23
23
  }
24
- const authorizationURL = `https://${config.domain}/oauth/v2/authorize`;
25
- const tokenURL = `https://${config.domain}/oauth/v2/token`;
24
+ const domain = hasProtocol(config.domain) ? config.domain : `https://${config.domain}`;
25
+ const authorizationURL = `${domain}/oauth/v2/authorize`;
26
+ const tokenURL = `${domain}/oauth/v2/token`;
26
27
  const redirectURL = config.redirectURL || getOAuthRedirectURL(event);
27
28
  const verifier = await handlePkceVerifier(event);
28
29
  const state = await handleState(event);
@@ -66,7 +67,7 @@ export function defineOAuthZitadelEventHandler({ config, onSuccess, onError }) {
66
67
  return handleAccessTokenErrorResponse(event, "zitadel", tokens, onError);
67
68
  }
68
69
  const accessToken = tokens.access_token;
69
- const user = await $fetch(`https://${config.domain}/oidc/v1/userinfo`, {
70
+ const user = await $fetch(`${domain}/oidc/v1/userinfo`, {
70
71
  headers: {
71
72
  Authorization: `Bearer ${accessToken}`,
72
73
  Accept: "application/json"
@@ -32,9 +32,9 @@ export declare function requestAccessToken(url: string, options: RequestAccessTo
32
32
  *
33
33
  * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
34
34
  */
35
- export declare function handleAccessTokenErrorResponse(event: H3Event, oauthProvider: OAuthProvider, oauthError: any, onError?: OnError): void | Promise<void>;
36
- export declare function handleMissingConfiguration(event: H3Event, provider: OAuthProvider, missingKeys: string[], onError?: OnError): void | Promise<void>;
37
- export declare function handleInvalidState(event: H3Event, provider: OAuthProvider, onError?: OnError): void | Promise<void>;
35
+ export declare function handleAccessTokenErrorResponse(event: H3Event, oauthProvider: OAuthProvider, oauthError: any, onError?: OnError): any;
36
+ export declare function handleMissingConfiguration(event: H3Event, provider: OAuthProvider, missingKeys: string[], onError?: OnError): any;
37
+ export declare function handleInvalidState(event: H3Event, provider: OAuthProvider, onError?: OnError): any;
38
38
  /**
39
39
  * JWT signing using jose
40
40
  *
@@ -61,13 +61,13 @@ interface JWTVerifyOptions {
61
61
  }
62
62
  export declare function verifyJwt<T>(token: string, options: JWTVerifyOptions): Promise<T>;
63
63
  export declare function handlePkceVerifier(event: H3Event): Promise<{
64
- code_verifier: string;
65
- code_challenge?: undefined;
66
- code_challenge_method?: undefined;
67
- } | {
68
64
  code_verifier: string;
69
65
  code_challenge: string;
70
66
  code_challenge_method: string;
67
+ } | {
68
+ code_verifier: string | undefined;
69
+ code_challenge?: undefined;
70
+ code_challenge_method?: undefined;
71
71
  }>;
72
- export declare function handleState(event: H3Event): Promise<string>;
72
+ export declare function handleState(event: H3Event): Promise<string | undefined>;
73
73
  export {};
@@ -1,10 +1,12 @@
1
- import { deleteCookie, getCookie, setCookie } from "h3";
1
+ import { deleteCookie, getCookie, getQuery, setCookie } from "h3";
2
2
  import { getRequestURL } from "h3";
3
3
  import { FetchError } from "ofetch";
4
4
  import { snakeCase, upperFirst } from "scule";
5
5
  import * as jose from "jose";
6
6
  import { subtle, getRandomValues } from "uncrypto";
7
7
  import { createError } from "#imports";
8
+ const isDevelopment = process.env.NODE_ENV === "development";
9
+ const OAUTH_COOKIE_MAX_AGE = 60 * 10;
8
10
  export function getOAuthRedirectURL(event) {
9
11
  const requestURL = getRequestURL(event);
10
12
  return `${requestURL.protocol}//${requestURL.host}${requestURL.pathname}`;
@@ -79,29 +81,43 @@ function getRandomBytes(size = 32) {
79
81
  return getRandomValues(new Uint8Array(size));
80
82
  }
81
83
  export async function handlePkceVerifier(event) {
82
- let verifier = getCookie(event, "nuxt-auth-pkce");
83
- if (verifier) {
84
- deleteCookie(event, "nuxt-auth-pkce");
85
- return { code_verifier: verifier };
84
+ const query = getQuery(event);
85
+ if (!query.code) {
86
+ const verifier2 = encodeBase64Url(getRandomBytes());
87
+ setCookie(event, "nuxt-auth-pkce", verifier2, {
88
+ httpOnly: true,
89
+ secure: !isDevelopment,
90
+ sameSite: "lax",
91
+ maxAge: OAUTH_COOKIE_MAX_AGE,
92
+ path: "/"
93
+ });
94
+ const encodedPkce = new TextEncoder().encode(verifier2);
95
+ const pkceHash = await subtle.digest("SHA-256", encodedPkce);
96
+ const pkce = encodeBase64Url(new Uint8Array(pkceHash));
97
+ return {
98
+ code_verifier: verifier2,
99
+ code_challenge: pkce,
100
+ code_challenge_method: "S256"
101
+ };
86
102
  }
87
- verifier = encodeBase64Url(getRandomBytes());
88
- setCookie(event, "nuxt-auth-pkce", verifier);
89
- const encodedPkce = new TextEncoder().encode(verifier);
90
- const pkceHash = await subtle.digest("SHA-256", encodedPkce);
91
- const pkce = encodeBase64Url(new Uint8Array(pkceHash));
92
- return {
93
- code_verifier: verifier,
94
- code_challenge: pkce,
95
- code_challenge_method: "S256"
96
- };
103
+ const verifier = getCookie(event, "nuxt-auth-pkce");
104
+ deleteCookie(event, "nuxt-auth-pkce");
105
+ return { code_verifier: verifier };
97
106
  }
98
107
  export async function handleState(event) {
99
- let state = getCookie(event, "nuxt-auth-state");
100
- if (state) {
108
+ const query = getQuery(event);
109
+ if (query.state) {
110
+ const state2 = getCookie(event, "nuxt-auth-state");
101
111
  deleteCookie(event, "nuxt-auth-state");
102
- return state;
112
+ return state2;
103
113
  }
104
- state = encodeBase64Url(getRandomBytes(8));
105
- setCookie(event, "nuxt-auth-state", state);
114
+ const state = encodeBase64Url(getRandomBytes(8));
115
+ setCookie(event, "nuxt-auth-state", state, {
116
+ httpOnly: true,
117
+ secure: !isDevelopment,
118
+ sameSite: "lax",
119
+ maxAge: OAUTH_COOKIE_MAX_AGE,
120
+ path: "/"
121
+ });
106
122
  return state;
107
123
  }
@@ -1,2 +1,2 @@
1
- declare const _default: import("nitropack").NitroAppPlugin;
1
+ declare const _default: import("nitropack/types").NitroAppPlugin;
2
2
  export default _default;
@@ -21,3 +21,20 @@ export declare function hashPassword(password: string): Promise<string>;
21
21
  * @more you can configure the scrypt options in `auth.hash.scrypt`
22
22
  */
23
23
  export declare function verifyPassword(hashedPassword: string, plainPassword: string): Promise<boolean>;
24
+ /**
25
+ * Check if the hash value needs a rehash or not. The rehash is required if
26
+ * configuration settings have changed.
27
+ * @param hashedPassword - The hashed password to check
28
+ * @returns `true` if a rehash is needed, `false` otherwise
29
+ * @example
30
+ * ```ts
31
+ * const isValid = await verifyPassword(hashedPassword, plainText)
32
+ *
33
+ * // Plain password is valid, and hash needs a rehash
34
+ * if (isValid && passwordNeedsReHash(hashedPassword)) {
35
+ * const newHash = await hashPassword(plainText)
36
+ * }
37
+ * ```
38
+ * @more you can configure the scrypt options in `auth.hash.scrypt`
39
+ */
40
+ export declare function passwordNeedsReHash(hashedPassword: string): boolean;
@@ -16,3 +16,6 @@ export async function hashPassword(password) {
16
16
  export async function verifyPassword(hashedPassword, plainPassword) {
17
17
  return await getHash().verify(hashedPassword, plainPassword);
18
18
  }
19
+ export function passwordNeedsReHash(hashedPassword) {
20
+ return getHash().needsReHash(hashedPassword);
21
+ }
@@ -1,5 +1,6 @@
1
1
  import type { H3Event, SessionConfig } from 'h3';
2
2
  import { useSession } from 'h3';
3
+ import type { OmitWithIndexSignature } from '../../types/utils.js';
3
4
  import type { UserSession, UserSessionRequired } from '#auth-utils';
4
5
  type UseSessionEvent = Parameters<typeof useSession>[0];
5
6
  export interface SessionHooks {
@@ -27,13 +28,13 @@ export declare function getUserSession(event: UseSessionEvent): Promise<UserSess
27
28
  * @param data User session data, please only store public information since it can be decoded with API calls
28
29
  * @see https://github.com/atinux/nuxt-auth-utils
29
30
  */
30
- export declare function setUserSession(event: H3Event, data: Omit<UserSession, 'id'>, config?: Partial<SessionConfig>): Promise<UserSession>;
31
+ export declare function setUserSession(event: H3Event, data: OmitWithIndexSignature<UserSession, 'id'>, config?: Partial<SessionConfig>): Promise<UserSession>;
31
32
  /**
32
33
  * Replace a user session
33
34
  * @param event The Request (h3) event
34
35
  * @param data User session data, please only store public information since it can be decoded with API calls
35
36
  */
36
- export declare function replaceUserSession(event: H3Event, data: Omit<UserSession, 'id'>, config?: Partial<SessionConfig>): Promise<UserSession>;
37
+ export declare function replaceUserSession(event: H3Event, data: OmitWithIndexSignature<UserSession, 'id'>, config?: Partial<SessionConfig>): Promise<UserSession>;
37
38
  /**
38
39
  * Clear the user session and removing the session cookie
39
40
  * @param event The Request (h3) event
@@ -1,6 +1,6 @@
1
1
  import type { H3Event, H3Error } from 'h3';
2
2
  export type ATProtoProvider = 'bluesky';
3
- export type OAuthProvider = ATProtoProvider | 'atlassian' | 'auth0' | 'authentik' | 'azureb2c' | 'battledotnet' | 'cognito' | 'discord' | 'dropbox' | 'facebook' | 'gitea' | 'github' | 'gitlab' | 'google' | 'hubspot' | 'instagram' | 'kick' | 'keycloak' | 'line' | 'linear' | 'linkedin' | 'microsoft' | 'paypal' | 'polar' | 'spotify' | 'seznam' | 'steam' | 'strava' | 'tiktok' | 'twitch' | 'vk' | 'workos' | 'x' | 'xsuaa' | 'yandex' | 'zitadel' | 'apple' | 'livechat' | 'salesforce' | 'slack' | 'heroku' | 'roblox' | 'okta' | 'ory' | (string & {});
3
+ export type OAuthProvider = ATProtoProvider | 'atlassian' | 'auth0' | 'authentik' | 'azureb2c' | 'battledotnet' | 'cognito' | 'discord' | 'dropbox' | 'facebook' | 'gitea' | 'github' | 'gitlab' | 'google' | 'hubspot' | 'instagram' | 'kick' | 'keycloak' | 'line' | 'linear' | 'linkedin' | 'microsoft' | 'paypal' | 'polar' | 'spotify' | 'seznam' | 'steam' | 'strava' | 'tiktok' | 'twitch' | 'vk' | 'workos' | 'x' | 'xsuaa' | 'yandex' | 'zitadel' | 'apple' | 'livechat' | 'salesforce' | 'slack' | 'heroku' | 'roblox' | 'okta' | 'ory' | 'shopifyCustomer' | (string & {});
4
4
  export type OnError = (event: H3Event, error: H3Error) => Promise<void> | void;
5
5
  export interface OAuthConfig<TConfig, TResult = {
6
6
  user: any;
@@ -0,0 +1,14 @@
1
+ type Prettify<T> = {
2
+ [K in keyof T]: T[K]
3
+ }
4
+
5
+ type RemoveIndexSignature<T> = {
6
+ [K in keyof T as string extends K ? never : K]: T[K]
7
+ }
8
+
9
+ type GetIndexSignature<T> = {
10
+ [K in keyof T as string extends K ? K : never]: T[K]
11
+ }
12
+
13
+ // Basic Omit but does not break if a [x:string]:unknown Index Signature is present in the type
14
+ export type OmitWithIndexSignature<T extends Record<string, unknown>, K extends keyof RemoveIndexSignature<T>> = Prettify<Omit<RemoveIndexSignature<T>, K> & GetIndexSignature<T>>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-auth-utils",
3
- "version": "0.5.25",
3
+ "version": "0.5.26",
4
4
  "description": "Add Authentication to Nuxt applications with secured & sealed cookies sessions.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "license": "MIT",
10
10
  "type": "module",
11
- "packageManager": "pnpm@10.16.1",
11
+ "packageManager": "pnpm@10.25.0",
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./dist/types.d.mts",
@@ -40,13 +40,13 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@adonisjs/hash": "^9.1.1",
43
- "@nuxt/kit": "^4.1.2",
43
+ "@nuxt/kit": "^4.2.1",
44
44
  "defu": "^6.1.4",
45
45
  "h3": "^1.15.4",
46
46
  "hookable": "^5.5.3",
47
- "jose": "^6.1.0",
48
- "ofetch": "^1.4.1",
49
- "openid-client": "^6.8.0",
47
+ "jose": "^6.1.3",
48
+ "ofetch": "^1.5.1",
49
+ "openid-client": "^6.8.1",
50
50
  "pathe": "^2.0.3",
51
51
  "scule": "^1.3.0",
52
52
  "uncrypto": "^0.1.3"
@@ -72,20 +72,20 @@
72
72
  }
73
73
  },
74
74
  "devDependencies": {
75
- "@iconify-json/simple-icons": "^1.2.52",
76
- "@nuxt/devtools": "2.6.3",
77
- "@nuxt/eslint-config": "^1.9.0",
75
+ "@iconify-json/simple-icons": "^1.2.62",
76
+ "@nuxt/devtools": "3.1.1",
77
+ "@nuxt/eslint-config": "^1.11.0",
78
78
  "@nuxt/module-builder": "^1.0.2",
79
- "@nuxt/schema": "^4.1.2",
80
- "@nuxt/test-utils": "^3.19.2",
79
+ "@nuxt/schema": "^4.2.1",
80
+ "@nuxt/test-utils": "^3.21.0",
81
81
  "@types/node": "latest",
82
- "@nuxt/ui": "^4.0.0-alpha.1",
82
+ "@nuxt/ui": "^4.2.1",
83
83
  "@simplewebauthn/types": "^12.0.0",
84
84
  "changelogen": "^0.6.2",
85
- "eslint": "^9.35.0",
86
- "nuxt": "^4.1.2",
87
- "typescript": "5.9.2",
88
- "vitest": "^3.2.4",
89
- "vue-tsc": "^3.0.7"
85
+ "eslint": "^9.39.1",
86
+ "nuxt": "^4.2.1",
87
+ "typescript": "5.9.3",
88
+ "vitest": "^4.0.15",
89
+ "vue-tsc": "^3.1.8"
90
90
  }
91
91
  }