nuxt-auth-utils 0.3.2 → 0.3.4

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 (39) hide show
  1. package/README.md +3 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +38 -20
  4. package/dist/runtime/server/lib/oauth/auth0.d.ts +5 -0
  5. package/dist/runtime/server/lib/oauth/auth0.js +3 -3
  6. package/dist/runtime/server/lib/oauth/battledotnet.d.ts +5 -0
  7. package/dist/runtime/server/lib/oauth/battledotnet.js +3 -4
  8. package/dist/runtime/server/lib/oauth/cognito.d.ts +5 -0
  9. package/dist/runtime/server/lib/oauth/cognito.js +3 -3
  10. package/dist/runtime/server/lib/oauth/discord.d.ts +5 -0
  11. package/dist/runtime/server/lib/oauth/discord.js +3 -3
  12. package/dist/runtime/server/lib/oauth/facebook.d.ts +5 -0
  13. package/dist/runtime/server/lib/oauth/facebook.js +3 -3
  14. package/dist/runtime/server/lib/oauth/github.d.ts +6 -0
  15. package/dist/runtime/server/lib/oauth/github.js +2 -2
  16. package/dist/runtime/server/lib/oauth/google.d.ts +5 -0
  17. package/dist/runtime/server/lib/oauth/google.js +3 -3
  18. package/dist/runtime/server/lib/oauth/keycloak.d.ts +5 -0
  19. package/dist/runtime/server/lib/oauth/keycloak.js +3 -3
  20. package/dist/runtime/server/lib/oauth/linkedin.d.ts +5 -0
  21. package/dist/runtime/server/lib/oauth/linkedin.js +3 -3
  22. package/dist/runtime/server/lib/oauth/microsoft.d.ts +1 -1
  23. package/dist/runtime/server/lib/oauth/microsoft.js +3 -3
  24. package/dist/runtime/server/lib/oauth/paypal.d.ts +5 -0
  25. package/dist/runtime/server/lib/oauth/paypal.js +3 -3
  26. package/dist/runtime/server/lib/oauth/spotify.d.ts +5 -0
  27. package/dist/runtime/server/lib/oauth/spotify.js +3 -3
  28. package/dist/runtime/server/lib/oauth/steam.d.ts +5 -0
  29. package/dist/runtime/server/lib/oauth/steam.js +2 -2
  30. package/dist/runtime/server/lib/oauth/twitch.d.ts +5 -0
  31. package/dist/runtime/server/lib/oauth/twitch.js +3 -3
  32. package/dist/runtime/server/lib/oauth/x.d.ts +5 -0
  33. package/dist/runtime/server/lib/oauth/x.js +3 -3
  34. package/dist/runtime/server/lib/oauth/xsuaa.d.ts +5 -0
  35. package/dist/runtime/server/lib/oauth/xsuaa.js +3 -3
  36. package/dist/runtime/server/lib/oauth/yandex.d.ts +5 -0
  37. package/dist/runtime/server/lib/oauth/yandex.js +3 -3
  38. package/dist/runtime/server/utils/session.js +3 -1
  39. package/package.json +9 -10
package/README.md CHANGED
@@ -233,6 +233,8 @@ export default oauthGitHubEventHandler({
233
233
 
234
234
  Make sure to set the callback URL in your OAuth app settings as `<your-domain>/auth/github`.
235
235
 
236
+ If the redirect URL mismatch in production, this means that the module cannot guess the right redirect URL. You can set the `NUXT_OAUTH_<PROVIDER>_REDIRECT_URL` env variable to overwrite the default one.
237
+
236
238
  ### Extend Session
237
239
 
238
240
  We leverage hooks to let you extend the session data with your own data or log when the user clears the session.
@@ -316,7 +318,7 @@ You can use the `placeholder` slot to show a placeholder on server-side and whil
316
318
  </template>
317
319
  ```
318
320
 
319
- If you are caching your routes with `routeRules`, please make sure to use [`nitro-nightly`](https://nitro.unjs.io/guide/nightly) or Nitro >= `2.10.0` to support the client-side fetching of the user session.
321
+ If you are caching your routes with `routeRules`, please make sure to use [Nitro](https://github.com/unjs/nitro) >= `2.9.7` to support the client-side fetching of the user session.
320
322
 
321
323
  ## Configuration
322
324
 
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "auth-utils",
3
3
  "configKey": "auth",
4
- "version": "0.3.2",
4
+ "version": "0.3.4",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.1",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -32,9 +32,10 @@ const module = defineNuxtModule({
32
32
  method: "get"
33
33
  });
34
34
  const runtimeConfig = nuxt.options.runtimeConfig;
35
+ const envSessionPassword = `${runtimeConfig.nitro?.envPrefix || "NUXT_"}SESSION_PASSWORD`;
35
36
  runtimeConfig.session = defu(runtimeConfig.session, {
36
37
  name: "nuxt-session",
37
- password: process.env.NUXT_SESSION_PASSWORD || "",
38
+ password: process.env[envSessionPassword] || "",
38
39
  cookie: {
39
40
  sameSite: "lax"
40
41
  }
@@ -43,10 +44,10 @@ const module = defineNuxtModule({
43
44
  runtimeConfig.session.password = randomUUID().replace(/-/g, "");
44
45
  const envPath = join(nuxt.options.rootDir, ".env");
45
46
  const envContent = await readFile(envPath, "utf-8").catch(() => "");
46
- if (!envContent.includes("NUXT_SESSION_PASSWORD")) {
47
+ if (!envContent.includes(envSessionPassword)) {
47
48
  await writeFile(
48
49
  envPath,
49
- `${envContent ? envContent + "\n" : envContent}NUXT_SESSION_PASSWORD=${runtimeConfig.session.password}`,
50
+ `${envContent ? envContent + "\n" : envContent}${envSessionPassword}=${runtimeConfig.session.password}`,
50
51
  "utf-8"
51
52
  );
52
53
  }
@@ -54,25 +55,30 @@ const module = defineNuxtModule({
54
55
  runtimeConfig.oauth = defu(runtimeConfig.oauth, {});
55
56
  runtimeConfig.oauth.github = defu(runtimeConfig.oauth.github, {
56
57
  clientId: "",
57
- clientSecret: ""
58
+ clientSecret: "",
59
+ redirectURL: ""
58
60
  });
59
61
  runtimeConfig.oauth.spotify = defu(runtimeConfig.oauth.spotify, {
60
62
  clientId: "",
61
- clientSecret: ""
63
+ clientSecret: "",
64
+ redirectURL: ""
62
65
  });
63
66
  runtimeConfig.oauth.google = defu(runtimeConfig.oauth.google, {
64
67
  clientId: "",
65
- clientSecret: ""
68
+ clientSecret: "",
69
+ redirectURL: ""
66
70
  });
67
71
  runtimeConfig.oauth.twitch = defu(runtimeConfig.oauth.twitch, {
68
72
  clientId: "",
69
- clientSecret: ""
73
+ clientSecret: "",
74
+ redirectURL: ""
70
75
  });
71
76
  runtimeConfig.oauth.auth0 = defu(runtimeConfig.oauth.auth0, {
72
77
  clientId: "",
73
78
  clientSecret: "",
74
79
  domain: "",
75
- audience: ""
80
+ audience: "",
81
+ redirectURL: ""
76
82
  });
77
83
  runtimeConfig.oauth.microsoft = defu(runtimeConfig.oauth.microsoft, {
78
84
  clientId: "",
@@ -81,55 +87,67 @@ const module = defineNuxtModule({
81
87
  scope: [],
82
88
  authorizationURL: "",
83
89
  tokenURL: "",
84
- userURL: ""
90
+ userURL: "",
91
+ redirectURL: ""
85
92
  });
86
93
  runtimeConfig.oauth.discord = defu(runtimeConfig.oauth.discord, {
87
94
  clientId: "",
88
- clientSecret: ""
95
+ clientSecret: "",
96
+ redirectURL: ""
89
97
  });
90
98
  runtimeConfig.oauth.battledotnet = defu(runtimeConfig.oauth.battledotnet, {
91
99
  clientId: "",
92
- clientSecret: ""
100
+ clientSecret: "",
101
+ redirectURL: ""
93
102
  });
94
103
  runtimeConfig.oauth.keycloak = defu(runtimeConfig.oauth.keycloak, {
95
104
  clientId: "",
96
105
  clientSecret: "",
97
106
  serverUrl: "",
98
- realm: ""
107
+ realm: "",
108
+ redirectURL: ""
99
109
  });
100
110
  runtimeConfig.oauth.linkedin = defu(runtimeConfig.oauth.linkedin, {
101
111
  clientId: "",
102
- clientSecret: ""
112
+ clientSecret: "",
113
+ redirectURL: ""
103
114
  });
104
115
  runtimeConfig.oauth.cognito = defu(runtimeConfig.oauth.cognito, {
105
116
  clientId: "",
106
117
  clientSecret: "",
107
118
  region: "",
108
- userPoolId: ""
119
+ userPoolId: "",
120
+ redirectURL: ""
109
121
  });
110
122
  runtimeConfig.oauth.facebook = defu(runtimeConfig.oauth.facebook, {
111
123
  clientId: "",
112
- clientSecret: ""
124
+ clientSecret: "",
125
+ redirectURL: ""
113
126
  });
114
127
  runtimeConfig.oauth.paypal = defu(runtimeConfig.oauth.paypal, {
115
128
  clientId: "",
116
- clientSecret: ""
129
+ clientSecret: "",
130
+ redirectURL: ""
117
131
  });
118
132
  runtimeConfig.oauth.steam = defu(runtimeConfig.oauth.steam, {
119
- apiKey: ""
133
+ apiKey: "",
134
+ redirectURL: ""
120
135
  });
121
136
  runtimeConfig.oauth.x = defu(runtimeConfig.oauth.x, {
122
137
  clientId: "",
123
- clientSecret: ""
138
+ clientSecret: "",
139
+ redirectURL: ""
124
140
  });
125
141
  runtimeConfig.oauth.xsuaa = defu(runtimeConfig.oauth.xsuaa, {
126
142
  clientId: "",
127
143
  clientSecret: "",
128
- domain: ""
144
+ domain: "",
145
+ redirectURL: ""
129
146
  });
130
147
  runtimeConfig.oauth.yandex = defu(runtimeConfig.oauth.yandex, {
131
148
  clientId: "",
132
- clientSecret: ""
149
+ clientSecret: "",
150
+ redirectURL: ""
133
151
  });
134
152
  }
135
153
  });
@@ -51,5 +51,10 @@ export interface OAuthAuth0Config {
51
51
  * @example { display: 'popup' }
52
52
  */
53
53
  authorizationParams?: Record<string, string>;
54
+ /**
55
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
56
+ * @default process.env.NUXT_OAUTH_AUTH0_REDIRECT_URL or current URL
57
+ */
58
+ redirectURL?: string;
54
59
  }
55
60
  export declare function oauthAuth0EventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthAuth0Config>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -18,7 +18,7 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
18
18
  }
19
19
  const authorizationURL = `https://${config.domain}/authorize`;
20
20
  const tokenURL = `https://${config.domain}/oauth/token`;
21
- const redirectUrl = getRequestURL(event).href;
21
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
22
22
  if (!code) {
23
23
  config.scope = config.scope || ["openid", "offline_access"];
24
24
  if (config.emailRequired && !config.scope.includes("email")) {
@@ -29,7 +29,7 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
29
29
  withQuery(authorizationURL, {
30
30
  response_type: "code",
31
31
  client_id: config.clientId,
32
- redirect_uri: redirectUrl,
32
+ redirect_uri: redirectURL,
33
33
  scope: config.scope.join(" "),
34
34
  audience: config.audience || "",
35
35
  max_age: config.maxAge || 0,
@@ -49,7 +49,7 @@ export function oauthAuth0EventHandler({ config, onSuccess, onError }) {
49
49
  grant_type: "authorization_code",
50
50
  client_id: config.clientId,
51
51
  client_secret: config.clientSecret,
52
- redirect_uri: parsePath(redirectUrl).pathname,
52
+ redirect_uri: parsePath(redirectURL).pathname,
53
53
  code
54
54
  }
55
55
  }
@@ -39,5 +39,10 @@ export interface OAuthBattledotnetConfig {
39
39
  * @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
40
40
  */
41
41
  authorizationParams?: Record<string, string>;
42
+ /**
43
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
44
+ * @default process.env.NUXT_OAUTH_BATTLEDOTNET_REDIRECT_URL or current URL
45
+ */
46
+ redirectURL?: string;
42
47
  }
43
48
  export declare function oauthBattledotnetEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthBattledotnetConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -29,6 +29,7 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
29
29
  if (!onError) throw error;
30
30
  return onError(event, error);
31
31
  }
32
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
32
33
  if (!code) {
33
34
  config.scope = config.scope || ["openid"];
34
35
  config.region = config.region || "EU";
@@ -36,12 +37,11 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
36
37
  config.authorizationURL = "https://oauth.battlenet.com.cn/authorize";
37
38
  config.tokenURL = "https://oauth.battlenet.com.cn/token";
38
39
  }
39
- const redirectUrl2 = getRequestURL(event).href;
40
40
  return sendRedirect(
41
41
  event,
42
42
  withQuery(config.authorizationURL, {
43
43
  client_id: config.clientId,
44
- redirect_uri: redirectUrl2,
44
+ redirect_uri: redirectURL,
45
45
  scope: config.scope.join(" "),
46
46
  state: randomUUID(),
47
47
  // Todo: handle PKCE flow
@@ -50,7 +50,6 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
50
50
  })
51
51
  );
52
52
  }
53
- const redirectUrl = getRequestURL(event).href;
54
53
  config.scope = config.scope || [];
55
54
  if (!config.scope.includes("openid")) {
56
55
  config.scope.push("openid");
@@ -68,7 +67,7 @@ export function oauthBattledotnetEventHandler({ config, onSuccess, onError }) {
68
67
  code,
69
68
  grant_type: "authorization_code",
70
69
  scope: config.scope.join(" "),
71
- redirect_uri: parsePath(redirectUrl).pathname
70
+ redirect_uri: parsePath(redirectURL).pathname
72
71
  }
73
72
  }
74
73
  ).catch((error) => {
@@ -30,5 +30,10 @@ export interface OAuthCognitoConfig {
30
30
  * @see https://docs.aws.amazon.com/cognito/latest/developerguide/authorization-endpoint.html
31
31
  */
32
32
  authorizationParams?: Record<string, string>;
33
+ /**
34
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
35
+ * @default process.env.NUXT_OAUTH_COGNITO_REDIRECT_URL or current URL
36
+ */
37
+ redirectURL?: string;
33
38
  }
34
39
  export declare function oauthCognitoEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthCognitoConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -18,14 +18,14 @@ export function oauthCognitoEventHandler({ config, onSuccess, onError }) {
18
18
  }
19
19
  const authorizationURL = `https://${config.userPoolId}.auth.${config.region}.amazoncognito.com/oauth2/authorize`;
20
20
  const tokenURL = `https://${config.userPoolId}.auth.${config.region}.amazoncognito.com/oauth2/token`;
21
- const redirectUrl = getRequestURL(event).href;
21
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
22
22
  if (!code) {
23
23
  config.scope = config.scope || ["openid", "profile"];
24
24
  return sendRedirect(
25
25
  event,
26
26
  withQuery(authorizationURL, {
27
27
  client_id: config.clientId,
28
- redirect_uri: redirectUrl,
28
+ redirect_uri: redirectURL,
29
29
  response_type: "code",
30
30
  scope: config.scope.join(" "),
31
31
  ...config.authorizationParams
@@ -39,7 +39,7 @@ export function oauthCognitoEventHandler({ config, onSuccess, onError }) {
39
39
  headers: {
40
40
  "Content-Type": "application/x-www-form-urlencoded"
41
41
  },
42
- body: `grant_type=authorization_code&client_id=${config.clientId}&client_secret=${config.clientSecret}&redirect_uri=${parsePath(redirectUrl).pathname}&code=${code}`
42
+ body: `grant_type=authorization_code&client_id=${config.clientId}&client_secret=${config.clientSecret}&redirect_uri=${parsePath(redirectURL).pathname}&code=${code}`
43
43
  }
44
44
  ).catch((error) => {
45
45
  return { error };
@@ -44,5 +44,10 @@ export interface OAuthDiscordConfig {
44
44
  * @example { allow_signup: 'true' }
45
45
  */
46
46
  authorizationParams?: Record<string, string>;
47
+ /**
48
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
49
+ * @default process.env.NUXT_OAUTH_DISCORD_REDIRECT_URL or current URL
50
+ */
51
+ redirectURL?: string;
47
52
  }
48
53
  export declare function oauthDiscordEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthDiscordConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -19,7 +19,7 @@ export function oauthDiscordEventHandler({ config, onSuccess, onError }) {
19
19
  if (!onError) throw error;
20
20
  return onError(event, error);
21
21
  }
22
- const redirectUrl = getRequestURL(event).href;
22
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
23
23
  if (!code) {
24
24
  config.scope = config.scope || [];
25
25
  if (config.emailRequired && !config.scope.includes("email")) {
@@ -33,13 +33,13 @@ export function oauthDiscordEventHandler({ config, onSuccess, onError }) {
33
33
  withQuery(config.authorizationURL, {
34
34
  response_type: "code",
35
35
  client_id: config.clientId,
36
- redirect_uri: redirectUrl,
36
+ redirect_uri: redirectURL,
37
37
  scope: config.scope.join(" "),
38
38
  ...config.authorizationParams
39
39
  })
40
40
  );
41
41
  }
42
- const parsedRedirectUrl = parseURL(redirectUrl);
42
+ const parsedRedirectUrl = parseURL(redirectURL);
43
43
  parsedRedirectUrl.search = "";
44
44
  const tokens = await $fetch(
45
45
  config.tokenURL,
@@ -39,5 +39,10 @@ export interface OAuthFacebookConfig {
39
39
  * @see https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/
40
40
  */
41
41
  authorizationParams?: Record<string, string>;
42
+ /**
43
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
44
+ * @default process.env.NUXT_OAUTH_FACEBOOK_REDIRECT_URL or current URL
45
+ */
46
+ redirectURL?: string;
42
47
  }
43
48
  export declare function oauthFacebookEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthFacebookConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -37,14 +37,14 @@ export function oauthFacebookEventHandler({
37
37
  if (!onError) throw error;
38
38
  return onError(event, error);
39
39
  }
40
- const redirectUrl = getRequestURL(event).href;
40
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
41
41
  if (!query.code) {
42
42
  config.scope = config.scope || [];
43
43
  return sendRedirect(
44
44
  event,
45
45
  withQuery(config.authorizationURL, {
46
46
  client_id: config.clientId,
47
- redirect_uri: redirectUrl,
47
+ redirect_uri: redirectURL,
48
48
  scope: config.scope.join(" ")
49
49
  })
50
50
  );
@@ -54,7 +54,7 @@ export function oauthFacebookEventHandler({
54
54
  body: {
55
55
  client_id: config.clientId,
56
56
  client_secret: config.clientSecret,
57
- redirect_uri: redirectUrl,
57
+ redirect_uri: redirectURL,
58
58
  code: query.code
59
59
  }
60
60
  });
@@ -38,5 +38,11 @@ export interface OAuthGitHubConfig {
38
38
  * @example { allow_signup: 'true' }
39
39
  */
40
40
  authorizationParams?: Record<string, string>;
41
+ /**
42
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
43
+ * @default process.env.NUXT_OAUTH_GITHUB_REDIRECT_URL
44
+ * @see https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps
45
+ */
46
+ redirectURL?: string;
41
47
  }
42
48
  export declare function oauthGitHubEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthGitHubConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -32,12 +32,12 @@ export function oauthGitHubEventHandler({ config, onSuccess, onError }) {
32
32
  if (config.emailRequired && !config.scope.includes("user:email")) {
33
33
  config.scope.push("user:email");
34
34
  }
35
- const redirectUrl = getRequestURL(event).href;
35
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
36
36
  return sendRedirect(
37
37
  event,
38
38
  withQuery(config.authorizationURL, {
39
39
  client_id: config.clientId,
40
- redirect_uri: redirectUrl,
40
+ redirect_uri: redirectURL,
41
41
  scope: config.scope.join(" "),
42
42
  ...config.authorizationParams
43
43
  })
@@ -38,5 +38,10 @@ export interface OAuthGoogleConfig {
38
38
  * @example { access_type: 'offline' }
39
39
  */
40
40
  authorizationParams?: Record<string, string>;
41
+ /**
42
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
43
+ * @default process.env.NUXT_OAUTH_GOOGLE_REDIRECT_URL or current URL
44
+ */
45
+ redirectURL?: string;
41
46
  }
42
47
  export declare function oauthGoogleEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthGoogleConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -29,7 +29,7 @@ export function oauthGoogleEventHandler({
29
29
  if (!onError) throw error;
30
30
  return onError(event, error);
31
31
  }
32
- const redirectUrl = getRequestURL(event).href;
32
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
33
33
  if (!code) {
34
34
  config.scope = config.scope || ["email", "profile"];
35
35
  return sendRedirect(
@@ -37,7 +37,7 @@ export function oauthGoogleEventHandler({
37
37
  withQuery(config.authorizationURL, {
38
38
  response_type: "code",
39
39
  client_id: config.clientId,
40
- redirect_uri: redirectUrl,
40
+ redirect_uri: redirectURL,
41
41
  scope: config.scope.join(" "),
42
42
  ...config.authorizationParams
43
43
  })
@@ -45,7 +45,7 @@ export function oauthGoogleEventHandler({
45
45
  }
46
46
  const body = {
47
47
  grant_type: "authorization_code",
48
- redirect_uri: parsePath(redirectUrl).pathname,
48
+ redirect_uri: parsePath(redirectURL).pathname,
49
49
  client_id: config.clientId,
50
50
  client_secret: config.clientSecret,
51
51
  code
@@ -32,5 +32,10 @@ export interface OAuthKeycloakConfig {
32
32
  * Extra authorization parameters to provide to the authorization URL
33
33
  */
34
34
  authorizationParams?: Record<string, string>;
35
+ /**
36
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
37
+ * @default process.env.NUXT_OAUTH_KEYCLOAK_REDIRECT_URL or current URL
38
+ */
39
+ redirectURL?: string;
35
40
  }
36
41
  export declare function oauthKeycloakEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthKeycloakConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -39,14 +39,14 @@ export function oauthKeycloakEventHandler({
39
39
  const realmURL = `${config.serverUrl}/realms/${config.realm}`;
40
40
  const authorizationURL = `${realmURL}/protocol/openid-connect/auth`;
41
41
  const tokenURL = `${realmURL}/protocol/openid-connect/token`;
42
- const redirectUrl = getRequestURL(event).href;
42
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
43
43
  if (!code) {
44
44
  config.scope = config.scope || ["openid"];
45
45
  return sendRedirect(
46
46
  event,
47
47
  withQuery(authorizationURL, {
48
48
  client_id: config.clientId,
49
- redirect_uri: redirectUrl,
49
+ redirect_uri: redirectURL,
50
50
  scope: config.scope.join(" "),
51
51
  response_type: "code",
52
52
  ...config.authorizationParams
@@ -66,7 +66,7 @@ export function oauthKeycloakEventHandler({
66
66
  client_id: config.clientId,
67
67
  client_secret: config.clientSecret,
68
68
  grant_type: "authorization_code",
69
- redirect_uri: parsePath(redirectUrl).pathname,
69
+ redirect_uri: parsePath(redirectURL).pathname,
70
70
  code
71
71
  }).toString()
72
72
  }).catch((error) => {
@@ -36,6 +36,11 @@ export interface OAuthLinkedInConfig {
36
36
  * @see https://docs.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/context
37
37
  */
38
38
  authorizationParams?: Record<string, string>;
39
+ /**
40
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
41
+ * @default process.env.NUXT_OAUTH_LINKEDIN_REDIRECT_URL or current URL
42
+ */
43
+ redirectURL?: string;
39
44
  }
40
45
  interface OAuthConfig {
41
46
  config?: OAuthLinkedInConfig;
@@ -18,7 +18,7 @@ export function oauthLinkedInEventHandler({ config, onSuccess, onError }) {
18
18
  if (!onError) throw error;
19
19
  return onError(event, error);
20
20
  }
21
- const redirectUrl = getRequestURL(event).href;
21
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
22
22
  if (!code) {
23
23
  config.scope = config.scope || [];
24
24
  if (!config.scope.length) {
@@ -32,13 +32,13 @@ export function oauthLinkedInEventHandler({ config, onSuccess, onError }) {
32
32
  withQuery(config.authorizationURL, {
33
33
  response_type: "code",
34
34
  client_id: config.clientId,
35
- redirect_uri: redirectUrl,
35
+ redirect_uri: redirectURL,
36
36
  scope: config.scope.join(" "),
37
37
  ...config.authorizationParams
38
38
  })
39
39
  );
40
40
  }
41
- const parsedRedirectUrl = parseURL(redirectUrl);
41
+ const parsedRedirectUrl = parseURL(redirectURL);
42
42
  parsedRedirectUrl.search = "";
43
43
  const tokens = await $fetch(
44
44
  config.tokenURL,
@@ -49,7 +49,7 @@ export interface OAuthMicrosoftConfig {
49
49
  * @default process.env.NUXT_OAUTH_MICROSOFT_REDIRECT_URL
50
50
  * @see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
51
51
  */
52
- redirectUrl?: string;
52
+ redirectURL?: string;
53
53
  }
54
54
  interface OAuthConfig {
55
55
  config?: OAuthMicrosoftConfig;
@@ -18,7 +18,7 @@ export function oauthMicrosoftEventHandler({ config, onSuccess, onError }) {
18
18
  }
19
19
  const authorizationURL = config.authorizationURL || `https://login.microsoftonline.com/${config.tenant}/oauth2/v2.0/authorize`;
20
20
  const tokenURL = config.tokenURL || `https://login.microsoftonline.com/${config.tenant}/oauth2/v2.0/token`;
21
- const redirectUrl = config.redirectUrl || getRequestURL(event).href;
21
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
22
22
  if (!code) {
23
23
  const scope = config.scope && config.scope.length > 0 ? config.scope : ["User.Read"];
24
24
  return sendRedirect(
@@ -26,7 +26,7 @@ export function oauthMicrosoftEventHandler({ config, onSuccess, onError }) {
26
26
  withQuery(authorizationURL, {
27
27
  client_id: config.clientId,
28
28
  response_type: "code",
29
- redirect_uri: redirectUrl,
29
+ redirect_uri: redirectURL,
30
30
  scope: scope.join(" "),
31
31
  ...config.authorizationParams
32
32
  })
@@ -36,7 +36,7 @@ export function oauthMicrosoftEventHandler({ config, onSuccess, onError }) {
36
36
  data.append("grant_type", "authorization_code");
37
37
  data.append("client_id", config.clientId);
38
38
  data.append("client_secret", config.clientSecret);
39
- data.append("redirect_uri", parsePath(redirectUrl).pathname);
39
+ data.append("redirect_uri", parsePath(redirectURL).pathname);
40
40
  data.append("code", String(code));
41
41
  const tokens = await $fetch(
42
42
  tokenURL,
@@ -43,5 +43,10 @@ export interface OAuthPaypalConfig {
43
43
  * @example { flowEntry: 'static' }
44
44
  */
45
45
  authorizationParams?: Record<string, string>;
46
+ /**
47
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
48
+ * @default process.env.NUXT_OAUTH_PAYPAL_REDIRECT_URL or current URL
49
+ */
50
+ redirectURL?: string;
46
51
  }
47
52
  export declare function oauthPaypalEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthPaypalConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -25,7 +25,7 @@ export function oauthPaypalEventHandler({ config, onSuccess, onError }) {
25
25
  config.authorizationURL = "https://www.sandbox.paypal.com/signin/authorize";
26
26
  config.tokenURL = `https://${paypalAPI}/v1/oauth2/token`;
27
27
  }
28
- const redirectUrl = getRequestURL(event).href;
28
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
29
29
  if (!code) {
30
30
  config.scope = config.scope || [];
31
31
  if (!config.scope.includes("openid")) {
@@ -39,7 +39,7 @@ export function oauthPaypalEventHandler({ config, onSuccess, onError }) {
39
39
  withQuery(config.authorizationURL, {
40
40
  response_type: "code",
41
41
  client_id: config.clientId,
42
- redirect_uri: redirectUrl,
42
+ redirect_uri: redirectURL,
43
43
  scope: config.scope.join(" "),
44
44
  flowEntry: "static",
45
45
  ...config.authorizationParams
@@ -57,7 +57,7 @@ export function oauthPaypalEventHandler({ config, onSuccess, onError }) {
57
57
  },
58
58
  params: {
59
59
  grant_type: "authorization_code",
60
- redirect_uri: encodeURIComponent(parsePath(redirectUrl).pathname),
60
+ redirect_uri: encodeURIComponent(parsePath(redirectURL).pathname),
61
61
  code
62
62
  }
63
63
  }
@@ -38,5 +38,10 @@ export interface OAuthSpotifyConfig {
38
38
  * @example { show_dialog: 'true' }
39
39
  */
40
40
  authorizationParams?: Record<string, string>;
41
+ /**
42
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
43
+ * @default process.env.NUXT_OAUTH_SPOTIFY_REDIRECT_URL or current URL
44
+ */
45
+ redirectURL?: string;
41
46
  }
42
47
  export declare function oauthSpotifyEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSpotifyConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -18,7 +18,7 @@ export function oauthSpotifyEventHandler({ config, onSuccess, onError }) {
18
18
  if (!onError) throw error;
19
19
  return onError(event, error);
20
20
  }
21
- const redirectUrl = getRequestURL(event).href;
21
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
22
22
  if (!code) {
23
23
  config.scope = config.scope || [];
24
24
  if (config.emailRequired && !config.scope.includes("user-read-email")) {
@@ -29,7 +29,7 @@ export function oauthSpotifyEventHandler({ config, onSuccess, onError }) {
29
29
  withQuery(config.authorizationURL, {
30
30
  response_type: "code",
31
31
  client_id: config.clientId,
32
- redirect_uri: redirectUrl,
32
+ redirect_uri: redirectURL,
33
33
  scope: config.scope.join(" "),
34
34
  ...config.authorizationParams
35
35
  })
@@ -46,7 +46,7 @@ export function oauthSpotifyEventHandler({ config, onSuccess, onError }) {
46
46
  },
47
47
  params: {
48
48
  grant_type: "authorization_code",
49
- redirect_uri: parsePath(redirectUrl).pathname,
49
+ redirect_uri: parsePath(redirectURL).pathname,
50
50
  code
51
51
  }
52
52
  }
@@ -11,5 +11,10 @@ export interface OAuthSteamConfig {
11
11
  * @default 'https://steamcommunity.com/openid/login'
12
12
  */
13
13
  authorizationURL?: string;
14
+ /**
15
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
16
+ * @default process.env.NUXT_OAUTH_STEAM_REDIRECT_URL or current URL
17
+ */
18
+ redirectURL?: string;
14
19
  }
15
20
  export declare function oauthSteamEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSteamConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -17,11 +17,11 @@ export function oauthSteamEventHandler({ config, onSuccess, onError }) {
17
17
  return onError(event, error);
18
18
  }
19
19
  if (!query["openid.claimed_id"]) {
20
- const redirectUrl = getRequestURL(event).href;
20
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
21
21
  const steamOpenIdParams = {
22
22
  "openid.ns": "http://specs.openid.net/auth/2.0",
23
23
  "openid.mode": "checkid_setup",
24
- "openid.return_to": redirectUrl,
24
+ "openid.return_to": redirectURL,
25
25
  "openid.identity": "http://specs.openid.net/auth/2.0/identifier_select",
26
26
  "openid.claimed_id": "http://specs.openid.net/auth/2.0/identifier_select"
27
27
  };
@@ -38,5 +38,10 @@ export interface OAuthTwitchConfig {
38
38
  * @example { force_verify: 'true' }
39
39
  */
40
40
  authorizationParams?: Record<string, string>;
41
+ /**
42
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
43
+ * @default process.env.NUXT_OAUTH_TWITCH_REDIRECT_URL or current URL
44
+ */
45
+ redirectURL?: string;
41
46
  }
42
47
  export declare function oauthTwitchEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthTwitchConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -18,7 +18,7 @@ export function oauthTwitchEventHandler({ config, onSuccess, onError }) {
18
18
  if (!onError) throw error;
19
19
  return onError(event, error);
20
20
  }
21
- const redirectUrl = getRequestURL(event).href;
21
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
22
22
  if (!code) {
23
23
  config.scope = config.scope || [];
24
24
  if (config.emailRequired && !config.scope.includes("user:read:email")) {
@@ -29,7 +29,7 @@ export function oauthTwitchEventHandler({ config, onSuccess, onError }) {
29
29
  withQuery(config.authorizationURL, {
30
30
  response_type: "code",
31
31
  client_id: config.clientId,
32
- redirect_uri: redirectUrl,
32
+ redirect_uri: redirectURL,
33
33
  scope: config.scope.join(" "),
34
34
  ...config.authorizationParams
35
35
  })
@@ -44,7 +44,7 @@ export function oauthTwitchEventHandler({ config, onSuccess, onError }) {
44
44
  },
45
45
  params: {
46
46
  grant_type: "authorization_code",
47
- redirect_uri: parsePath(redirectUrl).pathname,
47
+ redirect_uri: parsePath(redirectURL).pathname,
48
48
  client_id: config.clientId,
49
49
  client_secret: config.clientSecret,
50
50
  code
@@ -42,5 +42,10 @@ export interface OAuthXConfig {
42
42
  * @see https://developer.x.com/en/docs/authentication/oauth-2-0/user-access-token
43
43
  */
44
44
  authorizationParams: Record<string, string>;
45
+ /**
46
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
47
+ * @default process.env.NUXT_OAUTH_X_REDIRECT_URL or current URL
48
+ */
49
+ redirectURL?: string;
45
50
  }
46
51
  export declare function oauthXEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthXConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -33,7 +33,7 @@ export function oauthXEventHandler({
33
33
  if (!onError) throw error;
34
34
  return onError(event, error);
35
35
  }
36
- const redirectUrl = getRequestURL(event).href;
36
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
37
37
  if (!code) {
38
38
  config.scope = config.scope || ["tweet.read", "users.read", "offline.access"];
39
39
  return sendRedirect(
@@ -42,7 +42,7 @@ export function oauthXEventHandler({
42
42
  response_type: "code",
43
43
  client_id: config.clientId,
44
44
  code_challenge_method: "plain",
45
- redirect_uri: redirectUrl,
45
+ redirect_uri: redirectURL,
46
46
  scope: config.scope.join(" "),
47
47
  ...config.authorizationParams
48
48
  })
@@ -51,7 +51,7 @@ export function oauthXEventHandler({
51
51
  const params = {
52
52
  grant_type: "authorization_code",
53
53
  code_verifier: config.authorizationParams.code_challenge,
54
- redirect_uri: parsePath(redirectUrl).pathname,
54
+ redirect_uri: parsePath(redirectURL).pathname,
55
55
  code
56
56
  };
57
57
  const authCode = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString("base64");
@@ -22,5 +22,10 @@ export interface OAuthXSUAAConfig {
22
22
  * @example ['openid']
23
23
  */
24
24
  scope?: string[];
25
+ /**
26
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
27
+ * @default process.env.NUXT_OAUTH_XSUAA_REDIRECT_URL or current URL
28
+ */
29
+ redirectURL?: string;
25
30
  }
26
31
  export declare function oauthXSUAAEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthXSUAAConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -16,7 +16,7 @@ export function oauthXSUAAEventHandler({ config, onSuccess, onError }) {
16
16
  }
17
17
  const authorizationURL = `https://${config.domain}/oauth/authorize`;
18
18
  const tokenURL = `https://${config.domain}/oauth/token`;
19
- const redirectUrl = getRequestURL(event).href;
19
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
20
20
  if (!code) {
21
21
  config.scope = config.scope || [];
22
22
  return sendRedirect(
@@ -24,7 +24,7 @@ export function oauthXSUAAEventHandler({ config, onSuccess, onError }) {
24
24
  withQuery(authorizationURL, {
25
25
  response_type: "code",
26
26
  client_id: config.clientId,
27
- redirect_uri: redirectUrl,
27
+ redirect_uri: redirectURL,
28
28
  scope: config.scope.join(" ")
29
29
  })
30
30
  );
@@ -40,7 +40,7 @@ export function oauthXSUAAEventHandler({ config, onSuccess, onError }) {
40
40
  grant_type: "authorization_code",
41
41
  client_id: config.clientId,
42
42
  client_secret: config.clientSecret,
43
- redirect_uri: parsePath(redirectUrl).pathname,
43
+ redirect_uri: parsePath(redirectURL).pathname,
44
44
  code: `${code}`
45
45
  })
46
46
  }
@@ -37,5 +37,10 @@ export interface OAuthYandexConfig {
37
37
  * @default 'https://login.yandex.ru/info'
38
38
  */
39
39
  userURL?: string;
40
+ /**
41
+ * Redirect URL to to allow overriding for situations like prod failing to determine public hostname
42
+ * @default process.env.NUXT_OAUTH_YANDEX_REDIRECT_URL or current URL
43
+ */
44
+ redirectURL?: string;
40
45
  }
41
46
  export declare function oauthYandexEventHandler({ config, onSuccess, onError, }: OAuthConfig<OAuthYandexConfig>): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
@@ -28,7 +28,7 @@ export function oauthYandexEventHandler({
28
28
  if (!onError) throw error;
29
29
  return onError(event, error);
30
30
  }
31
- const redirectUrl = getRequestURL(event).href;
31
+ const redirectURL = config.redirectURL || getRequestURL(event).href;
32
32
  if (!code) {
33
33
  config.scope = config.scope || [];
34
34
  if (config.emailRequired && !config.scope.includes("login:email")) {
@@ -39,7 +39,7 @@ export function oauthYandexEventHandler({
39
39
  withQuery(config.authorizationURL, {
40
40
  response_type: "code",
41
41
  client_id: config.clientId,
42
- redirect_uri: redirectUrl,
42
+ redirect_uri: redirectURL,
43
43
  scope: config.scope.join(" ")
44
44
  })
45
45
  );
@@ -53,7 +53,7 @@ export function oauthYandexEventHandler({
53
53
  client_id: config.clientId,
54
54
  client_secret: config.clientSecret,
55
55
  grant_type: "authorization_code",
56
- redirect_uri: stringifyParsedURL(parseURL(redirectUrl)),
56
+ redirect_uri: stringifyParsedURL(parseURL(redirectURL)),
57
57
  code
58
58
  }).toString()
59
59
  }).catch((error) => {
@@ -36,7 +36,9 @@ export async function requireUserSession(event, opts = {}) {
36
36
  let sessionConfig;
37
37
  function _useSession(event) {
38
38
  if (!sessionConfig) {
39
- sessionConfig = defu({ password: process.env.NUXT_SESSION_PASSWORD }, useRuntimeConfig(event).session);
39
+ const runtimeConfig = useRuntimeConfig(event);
40
+ const envSessionPassword = `${runtimeConfig.nitro?.envPrefix || "NUXT_"}SESSION_PASSWORD`;
41
+ sessionConfig = defu({ password: process.env[envSessionPassword] }, runtimeConfig.session);
40
42
  }
41
43
  return useSession(event, sessionConfig);
42
44
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "nuxt-auth-utils",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Minimalist Auth module for Nuxt with SSR",
5
5
  "repository": "Atinux/nuxt-auth-utils",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
- "packageManager": "pnpm@9.1.3",
8
+ "packageManager": "pnpm@9.7.0",
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/types.d.ts",
@@ -41,20 +41,19 @@
41
41
  "uncrypto": "^0.1.3"
42
42
  },
43
43
  "devDependencies": {
44
- "@iconify-json/simple-icons": "^1.1.111",
44
+ "@iconify-json/simple-icons": "^1.1.113",
45
45
  "@nuxt/devtools": "latest",
46
- "@nuxt/eslint-config": "^0.4.0",
46
+ "@nuxt/eslint-config": "^0.5.0",
47
47
  "@nuxt/module-builder": "^0.8.1",
48
48
  "@nuxt/schema": "^3.12.4",
49
49
  "@nuxt/test-utils": "^3.14.0",
50
- "@nuxt/ui": "^2.18.2",
51
- "@nuxt/ui-pro": "^1.3.1",
52
- "@types/node": "^22.0.0",
50
+ "@nuxt/ui": "^2.18.4",
51
+ "@nuxt/ui-pro": "^1.4.1",
53
52
  "changelogen": "^0.5.5",
54
- "eslint": "^9.8.0",
53
+ "eslint": "^9.9.0",
55
54
  "nuxt": "^3.12.4",
56
55
  "typescript": "^5.5.4",
57
- "vitest": "^2.0.4",
56
+ "vitest": "^2.0.5",
58
57
  "vue-tsc": "^2.0.29"
59
58
  }
60
- }
59
+ }