@aura-stack/auth 0.4.0 → 0.5.0

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 (149) hide show
  1. package/dist/@types/index.d.ts +6 -2
  2. package/dist/@types/router.d.d.ts +6 -2
  3. package/dist/actions/callback/access-token.cjs +103 -59
  4. package/dist/actions/callback/access-token.d.ts +7 -3
  5. package/dist/actions/callback/access-token.js +3 -3
  6. package/dist/actions/callback/callback.cjs +200 -134
  7. package/dist/actions/callback/callback.d.ts +32 -3
  8. package/dist/actions/callback/callback.js +11 -12
  9. package/dist/actions/callback/userinfo.cjs +103 -70
  10. package/dist/actions/callback/userinfo.d.ts +6 -2
  11. package/dist/actions/callback/userinfo.js +7 -8
  12. package/dist/actions/csrfToken/csrfToken.cjs +7 -15
  13. package/dist/actions/csrfToken/csrfToken.d.ts +3 -1
  14. package/dist/actions/csrfToken/csrfToken.js +7 -8
  15. package/dist/actions/index.cjs +502 -295
  16. package/dist/actions/index.d.ts +5 -2
  17. package/dist/actions/index.js +23 -20
  18. package/dist/actions/session/session.cjs +76 -24
  19. package/dist/actions/session/session.d.ts +3 -1
  20. package/dist/actions/session/session.js +6 -4
  21. package/dist/actions/signIn/authorization-url.cjs +288 -0
  22. package/dist/actions/signIn/authorization-url.d.ts +31 -0
  23. package/dist/actions/signIn/authorization-url.js +16 -0
  24. package/dist/actions/signIn/authorization.cjs +91 -132
  25. package/dist/actions/signIn/authorization.d.ts +17 -16
  26. package/dist/actions/signIn/authorization.js +8 -7
  27. package/dist/actions/signIn/signIn.cjs +319 -191
  28. package/dist/actions/signIn/signIn.d.ts +32 -3
  29. package/dist/actions/signIn/signIn.js +10 -9
  30. package/dist/actions/signOut/signOut.cjs +211 -212
  31. package/dist/actions/signOut/signOut.d.ts +9 -1
  32. package/dist/actions/signOut/signOut.js +9 -10
  33. package/dist/api/createApi.cjs +750 -0
  34. package/dist/api/createApi.d.ts +12 -0
  35. package/dist/api/createApi.js +19 -0
  36. package/dist/api/getSession.cjs +141 -0
  37. package/dist/api/getSession.d.ts +16 -0
  38. package/dist/api/getSession.js +10 -0
  39. package/dist/api/signIn.cjs +549 -0
  40. package/dist/api/signIn.d.ts +26 -0
  41. package/dist/api/signIn.js +15 -0
  42. package/dist/api/signOut.cjs +279 -0
  43. package/dist/api/signOut.d.ts +16 -0
  44. package/dist/api/signOut.js +13 -0
  45. package/dist/assert.cjs +42 -9
  46. package/dist/assert.d.ts +8 -4
  47. package/dist/assert.js +5 -5
  48. package/dist/{chunk-KJBAQZX2.js → chunk-2A5B7GWR.js} +44 -11
  49. package/dist/chunk-2GQLSIJ2.js +40 -0
  50. package/dist/chunk-2IR674WX.js +44 -0
  51. package/dist/chunk-3J5TUH2I.js +50 -0
  52. package/dist/chunk-4RWSYUKX.js +98 -0
  53. package/dist/chunk-5X7JZMEF.js +0 -0
  54. package/dist/{chunk-TZB6MUXN.js → chunk-7BE46WWS.js} +21 -11
  55. package/dist/chunk-7YYXFKLR.js +35 -0
  56. package/dist/chunk-C3A37LQC.js +33 -0
  57. package/dist/chunk-CITNGXDA.js +31 -0
  58. package/dist/chunk-CWX724AG.js +78 -0
  59. package/dist/chunk-D2CSIUKP.js +74 -0
  60. package/dist/{chunk-ICAZ4OVS.js → chunk-FPCVZUVG.js} +2 -2
  61. package/dist/{chunk-XGLBNXL4.js → chunk-GNNBM2WJ.js} +17 -9
  62. package/dist/chunk-JOCGX3RP.js +59 -0
  63. package/dist/chunk-KBXWTD6E.js +94 -0
  64. package/dist/{chunk-XUP6KKNG.js → chunk-LATR3NIV.js} +48 -37
  65. package/dist/chunk-LAYPUDQF.js +39 -0
  66. package/dist/chunk-LX3TJ2TJ.js +294 -0
  67. package/dist/{chunk-6MXFPFR3.js → chunk-NHZBQNRR.js} +19 -19
  68. package/dist/{chunk-TM5IPSNF.js → chunk-PDP3PHB3.js} +33 -19
  69. package/dist/chunk-PHYNROD4.js +47 -0
  70. package/dist/chunk-QQEKY4XP.js +29 -0
  71. package/dist/{chunk-VNCNJKS2.js → chunk-U4RK4LKJ.js} +82 -1
  72. package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
  73. package/dist/chunk-UN7X6SU5.js +53 -0
  74. package/dist/chunk-UZQJJD6A.js +100 -0
  75. package/dist/{chunk-NUDITUKX.js → chunk-V6LLEAR4.js} +22 -15
  76. package/dist/{chunk-4MYWAOLG.js → chunk-WHNDRO3N.js} +20 -1
  77. package/dist/{chunk-5W4BRQYG.js → chunk-XY5R3EHH.js} +6 -3
  78. package/dist/client/client.cjs +135 -0
  79. package/dist/client/client.d.ts +85 -0
  80. package/dist/client/client.js +9 -0
  81. package/dist/client/index.cjs +135 -0
  82. package/dist/client/index.d.ts +14 -0
  83. package/dist/client/index.js +10 -0
  84. package/dist/context.cjs +1237 -0
  85. package/dist/context.d.ts +16 -0
  86. package/dist/context.js +28 -0
  87. package/dist/cookie.cjs +33 -2
  88. package/dist/cookie.d.ts +9 -5
  89. package/dist/cookie.js +3 -2
  90. package/dist/createAuth.cjs +2320 -0
  91. package/dist/createAuth.d.ts +12 -0
  92. package/dist/createAuth.js +48 -0
  93. package/dist/env.cjs +24 -2
  94. package/dist/env.d.ts +4 -1
  95. package/dist/env.js +9 -3
  96. package/dist/errors.cjs +17 -0
  97. package/dist/errors.d.ts +13 -3
  98. package/dist/errors.js +5 -1
  99. package/dist/{index-CSyIJmCM.d.ts → index-_aXtxb_s.d.ts} +383 -13
  100. package/dist/index.cjs +2135 -1547
  101. package/dist/index.d.ts +9 -30
  102. package/dist/index.js +46 -119
  103. package/dist/jose.cjs +52 -14
  104. package/dist/jose.d.ts +12 -25
  105. package/dist/jose.js +11 -3
  106. package/dist/logger.cjs +132 -0
  107. package/dist/logger.d.ts +6 -2
  108. package/dist/logger.js +10 -1
  109. package/dist/oauth/atlassian.cjs +57 -0
  110. package/dist/oauth/atlassian.d.ts +12 -0
  111. package/dist/oauth/atlassian.js +6 -0
  112. package/dist/oauth/bitbucket.d.ts +6 -2
  113. package/dist/oauth/discord.d.ts +6 -2
  114. package/dist/oauth/dropbox.cjs +53 -0
  115. package/dist/oauth/dropbox.d.ts +12 -0
  116. package/dist/oauth/dropbox.js +6 -0
  117. package/dist/oauth/figma.d.ts +6 -2
  118. package/dist/oauth/github.d.ts +6 -2
  119. package/dist/oauth/gitlab.d.ts +6 -2
  120. package/dist/oauth/index.cjs +278 -88
  121. package/dist/oauth/index.d.ts +6 -2
  122. package/dist/oauth/index.js +27 -11
  123. package/dist/oauth/mailchimp.d.ts +6 -2
  124. package/dist/oauth/notion.cjs +131 -0
  125. package/dist/oauth/notion.d.ts +12 -0
  126. package/dist/oauth/notion.js +9 -0
  127. package/dist/oauth/pinterest.d.ts +6 -2
  128. package/dist/oauth/spotify.d.ts +6 -2
  129. package/dist/oauth/strava.d.ts +6 -2
  130. package/dist/oauth/twitch.cjs +95 -0
  131. package/dist/oauth/twitch.d.ts +12 -0
  132. package/dist/oauth/twitch.js +7 -0
  133. package/dist/oauth/x.d.ts +6 -2
  134. package/dist/schemas.cjs +84 -51
  135. package/dist/schemas.d.ts +103 -23
  136. package/dist/schemas.js +1 -1
  137. package/dist/secure.cjs +36 -36
  138. package/dist/secure.d.ts +10 -4
  139. package/dist/secure.js +7 -6
  140. package/dist/utils.cjs +109 -3
  141. package/dist/utils.d.ts +15 -4
  142. package/dist/utils.js +11 -4
  143. package/package.json +9 -5
  144. package/dist/chunk-4EKY7655.js +0 -123
  145. package/dist/chunk-7QF22LHP.js +0 -67
  146. package/dist/chunk-ALG3GIV4.js +0 -95
  147. package/dist/chunk-FRJFWTOY.js +0 -70
  148. package/dist/chunk-PHFH2MGS.js +0 -36
  149. package/dist/chunk-QQVSRXGX.js +0 -149
@@ -0,0 +1,98 @@
1
+ import {
2
+ AuthClientError,
3
+ isNativeError
4
+ } from "./chunk-U5663F2U.js";
5
+
6
+ // src/client/client.ts
7
+ import { createClient as createClientAPI } from "@aura-stack/router";
8
+ var createClient = createClientAPI;
9
+ var createAuthClient = (options) => {
10
+ if (typeof window === "undefined" && !options.baseURL) {
11
+ throw new AuthClientError("`baseURL` is required when createAuthClient is used outside the browser.");
12
+ }
13
+ const client = createClient({
14
+ cache: "no-store",
15
+ credentials: "include",
16
+ baseURL: options.baseURL ?? window.location.origin,
17
+ ...options
18
+ });
19
+ const getCSRFToken = async () => {
20
+ try {
21
+ const response = await client.get("/csrfToken");
22
+ if (!response.ok) return null;
23
+ const data = await response.json();
24
+ return data.csrfToken;
25
+ } catch (error) {
26
+ console.error("Error fetching CSRF token:", error);
27
+ return null;
28
+ }
29
+ };
30
+ const getSession = async () => {
31
+ try {
32
+ const response = await client.get("/session");
33
+ if (!response.ok) return null;
34
+ const session = await response.json();
35
+ if (!session?.authenticated) return null;
36
+ return session.session;
37
+ } catch (error) {
38
+ console.error("Error fetching session:", error);
39
+ return null;
40
+ }
41
+ };
42
+ const signIn = async (oauth, options2) => {
43
+ try {
44
+ const response = await client.get("/signIn/:oauth", {
45
+ params: {
46
+ oauth
47
+ },
48
+ searchParams: {
49
+ ...options2,
50
+ redirect: false
51
+ }
52
+ });
53
+ const json = await response.json();
54
+ if ((options2?.redirect ?? true) && typeof window !== "undefined" && json?.signInURL) {
55
+ window.location.assign(json.signInURL);
56
+ }
57
+ return json;
58
+ } catch (error) {
59
+ console.error("Error during sign-in:", error);
60
+ return { redirect: false, signInURL: "/" };
61
+ }
62
+ };
63
+ const signOut = async (options2) => {
64
+ try {
65
+ const csrfToken = await getCSRFToken();
66
+ if (!csrfToken) {
67
+ throw new AuthClientError("Failed to fetch CSRF token for sign-out.");
68
+ }
69
+ const response = await client.post("/signOut", {
70
+ searchParams: {
71
+ redirectTo: options2?.redirectTo ?? "/",
72
+ token_type_hint: "session_token"
73
+ },
74
+ headers: {
75
+ "X-CSRF-Token": csrfToken
76
+ }
77
+ });
78
+ const json = await response.json();
79
+ if ((options2?.redirect ?? true) && typeof window !== "undefined" && json?.url) {
80
+ window.location.assign(json.url);
81
+ }
82
+ return json;
83
+ } catch (error) {
84
+ console.error("Error during sign-out:", error);
85
+ throw isNativeError(error) ? error : new AuthClientError("Sign-out failed.", "The sign-out request failed.", { cause: error });
86
+ }
87
+ };
88
+ return {
89
+ getSession,
90
+ signIn,
91
+ signOut
92
+ };
93
+ };
94
+
95
+ export {
96
+ createClient,
97
+ createAuthClient
98
+ };
File without changes
@@ -2,42 +2,52 @@ import {
2
2
  fetchAsync
3
3
  } from "./chunk-ZNCZVF6U.js";
4
4
  import {
5
- OAuthAccessToken,
6
5
  OAuthAccessTokenErrorResponse,
7
6
  OAuthAccessTokenResponse
8
- } from "./chunk-KJBAQZX2.js";
7
+ } from "./chunk-2A5B7GWR.js";
9
8
  import {
10
9
  AuthInternalError,
11
10
  OAuthProtocolError
12
- } from "./chunk-RRLIF4PQ.js";
11
+ } from "./chunk-U5663F2U.js";
13
12
 
14
13
  // src/actions/callback/access-token.ts
15
14
  var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier, logger) => {
16
- const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
17
- if (!parsed.success) {
18
- logger?.log("INVALID_OAUTH_CONFIGURATION");
15
+ const { accessToken, clientId, clientSecret } = oauthConfig;
16
+ if (!clientId || !clientSecret || !redirectURI || !code || !codeVerifier || !accessToken) {
17
+ logger?.log("INVALID_OAUTH_CONFIGURATION", {
18
+ structuredData: {
19
+ has_client_id: Boolean(clientId),
20
+ has_client_secret: Boolean(clientSecret),
21
+ has_access_token: Boolean(accessToken),
22
+ has_redirect_uri: Boolean(redirectURI),
23
+ has_code: Boolean(code),
24
+ has_code_verifier: Boolean(codeVerifier)
25
+ }
26
+ });
19
27
  throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
20
28
  }
21
- const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
29
+ const tokenURL = typeof accessToken === "string" ? accessToken : accessToken.url;
30
+ const extraHeaders = typeof accessToken === "string" ? void 0 : accessToken.headers;
22
31
  try {
23
32
  logger?.log("OAUTH_ACCESS_TOKEN_REQUEST_INITIATED", {
24
33
  structuredData: {
25
34
  has_client_id: Boolean(clientId),
26
- redirect_uri: redirectParsed,
35
+ redirect_uri: redirectURI,
27
36
  grant_type: "authorization_code"
28
37
  }
29
38
  });
30
- const response = await fetchAsync(accessToken, {
39
+ const response = await fetchAsync(tokenURL, {
31
40
  method: "POST",
32
41
  headers: {
42
+ ...extraHeaders ?? {},
33
43
  Accept: "application/json",
34
44
  "Content-Type": "application/x-www-form-urlencoded"
35
45
  },
36
46
  body: new URLSearchParams({
37
47
  client_id: clientId,
38
48
  client_secret: clientSecret,
39
- code: codeParsed,
40
- redirect_uri: redirectParsed,
49
+ code,
50
+ redirect_uri: redirectURI,
41
51
  grant_type: "authorization_code",
42
52
  code_verifier: codeVerifier
43
53
  }).toString()
@@ -0,0 +1,35 @@
1
+ import {
2
+ getSession
3
+ } from "./chunk-CITNGXDA.js";
4
+ import {
5
+ expiredCookieAttributes
6
+ } from "./chunk-XY5R3EHH.js";
7
+ import {
8
+ AuthInternalError
9
+ } from "./chunk-U5663F2U.js";
10
+ import {
11
+ secureApiHeaders
12
+ } from "./chunk-EBAMFRB7.js";
13
+
14
+ // src/actions/session/session.ts
15
+ import { createEndpoint, HeadersBuilder } from "@aura-stack/router";
16
+ var sessionAction = createEndpoint("GET", "/session", async (ctx) => {
17
+ const {
18
+ request,
19
+ context: { cookies }
20
+ } = ctx;
21
+ try {
22
+ const session = await getSession({ ctx: ctx.context, headers: request.headers });
23
+ if (!session.authenticated) {
24
+ throw new AuthInternalError("INVALID_JWT_TOKEN", "Session not authenticated");
25
+ }
26
+ return Response.json(session, { headers: secureApiHeaders });
27
+ } catch (error) {
28
+ const headers = new HeadersBuilder(secureApiHeaders).setCookie(cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
29
+ return Response.json({ session: null, authenticated: false }, { status: 401, headers });
30
+ }
31
+ });
32
+
33
+ export {
34
+ sessionAction
35
+ };
@@ -0,0 +1,33 @@
1
+ // src/oauth/atlassian.ts
2
+ var atlassian = (options) => {
3
+ return {
4
+ id: "atlassian",
5
+ name: "Atlassian",
6
+ authorize: {
7
+ url: "https://auth.atlassian.com/authorize",
8
+ params: {
9
+ audience: "api.atlassian.com",
10
+ scope: "read:me read:account",
11
+ prompt: "consent"
12
+ }
13
+ },
14
+ authorizeURL: "https://auth.atlassian.com/authorize",
15
+ accessToken: "https://auth.atlassian.com/oauth/token",
16
+ userInfo: "https://api.atlassian.com/me",
17
+ scope: "read:me read:account",
18
+ responseType: "code",
19
+ profile(profile) {
20
+ return {
21
+ sub: profile.account_id,
22
+ name: profile.name,
23
+ email: profile.email,
24
+ image: profile.picture
25
+ };
26
+ },
27
+ ...options
28
+ };
29
+ };
30
+
31
+ export {
32
+ atlassian
33
+ };
@@ -0,0 +1,31 @@
1
+ import {
2
+ getErrorName,
3
+ toISOString
4
+ } from "./chunk-LX3TJ2TJ.js";
5
+ import {
6
+ getCookie
7
+ } from "./chunk-XY5R3EHH.js";
8
+
9
+ // src/api/getSession.ts
10
+ var getSession = async ({ ctx, headers }) => {
11
+ try {
12
+ const session = getCookie(new Headers(headers), ctx.cookies.sessionToken.name);
13
+ const decoded = await ctx.jose.decodeJWT(session);
14
+ ctx?.logger?.log("AUTH_SESSION_VALID");
15
+ const { exp, iat, jti, nbf, aud, iss, ...user } = decoded;
16
+ return {
17
+ session: {
18
+ user,
19
+ expires: toISOString(exp * 1e3)
20
+ },
21
+ authenticated: true
22
+ };
23
+ } catch (error) {
24
+ ctx?.logger?.log("AUTH_SESSION_INVALID", { structuredData: { error_type: getErrorName(error) } });
25
+ return { session: null, authenticated: false };
26
+ }
27
+ };
28
+
29
+ export {
30
+ getSession
31
+ };
@@ -0,0 +1,78 @@
1
+ import {
2
+ callbackAction
3
+ } from "./chunk-NHZBQNRR.js";
4
+ import {
5
+ csrfTokenAction
6
+ } from "./chunk-FPCVZUVG.js";
7
+ import {
8
+ signInAction
9
+ } from "./chunk-UN7X6SU5.js";
10
+ import {
11
+ sessionAction
12
+ } from "./chunk-7YYXFKLR.js";
13
+ import {
14
+ signOutAction
15
+ } from "./chunk-3J5TUH2I.js";
16
+ import {
17
+ createAuthAPI
18
+ } from "./chunk-LAYPUDQF.js";
19
+ import {
20
+ createContext
21
+ } from "./chunk-2IR674WX.js";
22
+ import {
23
+ createErrorHandler,
24
+ useSecureCookies
25
+ } from "./chunk-LX3TJ2TJ.js";
26
+
27
+ // src/createAuth.ts
28
+ import { createRouter } from "@aura-stack/router";
29
+ var createInternalConfig = (authConfig) => {
30
+ const context = createContext(authConfig);
31
+ return {
32
+ basePath: authConfig?.basePath ?? "/auth",
33
+ onError: createErrorHandler(context.logger),
34
+ context,
35
+ use: [
36
+ (ctx) => {
37
+ const useSecure = useSecureCookies(ctx.request, ctx.context.trustedProxyHeaders);
38
+ ctx.context.cookies = useSecure ? context.cookieConfig.secure : context.cookieConfig.standard;
39
+ return ctx;
40
+ }
41
+ ]
42
+ };
43
+ };
44
+ var createAuthInstance = (authConfig) => {
45
+ const config = createInternalConfig(authConfig);
46
+ const router = createRouter(
47
+ [signInAction(config.context.oauth), callbackAction(config.context.oauth), sessionAction, signOutAction, csrfTokenAction],
48
+ config
49
+ );
50
+ return {
51
+ handlers: router,
52
+ jose: config.context.jose,
53
+ api: createAuthAPI(config.context)
54
+ };
55
+ };
56
+ var createAuth = (config) => {
57
+ const authInstance = createAuthInstance(config);
58
+ authInstance.handlers.ALL = async (request) => {
59
+ const method = request.method.toUpperCase();
60
+ const methodHandlers = {
61
+ GET: authInstance.handlers.GET,
62
+ POST: authInstance.handlers.POST
63
+ };
64
+ if (method in methodHandlers) {
65
+ return await methodHandlers[method](request);
66
+ }
67
+ return new Response("Method Not Allowed", {
68
+ status: 405,
69
+ headers: { Allow: Object.keys(methodHandlers).join(", ") }
70
+ });
71
+ };
72
+ return authInstance;
73
+ };
74
+
75
+ export {
76
+ createAuthInstance,
77
+ createAuth
78
+ };
@@ -0,0 +1,74 @@
1
+ import {
2
+ createPKCE,
3
+ createSecretValue
4
+ } from "./chunk-V6LLEAR4.js";
5
+ import {
6
+ OAuthAuthorization
7
+ } from "./chunk-2A5B7GWR.js";
8
+ import {
9
+ AuthInternalError
10
+ } from "./chunk-U5663F2U.js";
11
+
12
+ // src/actions/signIn/authorization-url.ts
13
+ var setSearchParams = (url, params) => {
14
+ for (const [key, value] of Object.entries(params)) {
15
+ if (value !== void 0 && value !== "") {
16
+ url.searchParams.set(key, value);
17
+ }
18
+ }
19
+ };
20
+ var buildAuthorizationURL = (oauth, redirect_uri, state, code_challenge, code_challenge_method) => {
21
+ const authorizeConfig = oauth.authorize;
22
+ const baseURL = typeof authorizeConfig === "string" ? authorizeConfig : authorizeConfig?.url ?? oauth.authorizeURL;
23
+ if (!baseURL) {
24
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "Missing authorization URL in OAuth provider configuration.");
25
+ }
26
+ const url = new URL(baseURL);
27
+ const authorizeParams = typeof authorizeConfig === "string" ? void 0 : authorizeConfig?.params;
28
+ setSearchParams(url, {
29
+ response_type: authorizeParams?.responseType ?? oauth.responseType ?? "code",
30
+ client_id: oauth.clientId,
31
+ redirect_uri,
32
+ state,
33
+ code_challenge,
34
+ code_challenge_method,
35
+ scope: authorizeParams?.scope ?? oauth.scope,
36
+ prompt: authorizeParams?.prompt,
37
+ response_mode: authorizeParams?.responseMode,
38
+ login_hint: authorizeParams?.loginHint,
39
+ nonce: authorizeParams?.nonce,
40
+ display: authorizeParams?.display,
41
+ audience: authorizeParams?.audience
42
+ });
43
+ return url.toString();
44
+ };
45
+ var createAuthorizationURL = async (oauth, redirectURI, ctx) => {
46
+ const state = createSecretValue();
47
+ const { codeVerifier, codeChallenge, method } = await createPKCE();
48
+ const authorization = buildAuthorizationURL(oauth, redirectURI, state, codeChallenge, method);
49
+ const parsed = OAuthAuthorization.safeParse({ ...oauth, redirectURI, state, codeChallenge, codeChallengeMethod: method });
50
+ if (!parsed.success) {
51
+ ctx?.logger?.log("INVALID_OAUTH_CONFIGURATION", {
52
+ structuredData: {
53
+ scope: oauth?.scope ?? "",
54
+ redirect_uri: redirectURI,
55
+ has_state: Boolean(state),
56
+ has_code_challenge: Boolean(codeChallenge),
57
+ code_challenge_method: method
58
+ }
59
+ });
60
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
61
+ }
62
+ return {
63
+ authorization,
64
+ state,
65
+ codeVerifier,
66
+ method
67
+ };
68
+ };
69
+
70
+ export {
71
+ setSearchParams,
72
+ buildAuthorizationURL,
73
+ createAuthorizationURL
74
+ };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createCSRF
3
- } from "./chunk-NUDITUKX.js";
3
+ } from "./chunk-V6LLEAR4.js";
4
4
  import {
5
5
  getCookie,
6
6
  setCookie
7
- } from "./chunk-5W4BRQYG.js";
7
+ } from "./chunk-XY5R3EHH.js";
8
8
  import {
9
9
  secureApiHeaders
10
10
  } from "./chunk-EBAMFRB7.js";
@@ -1,17 +1,20 @@
1
1
  import {
2
2
  fetchAsync
3
3
  } from "./chunk-ZNCZVF6U.js";
4
+ import {
5
+ generateSecure
6
+ } from "./chunk-V6LLEAR4.js";
4
7
  import {
5
8
  OAuthErrorResponse
6
- } from "./chunk-KJBAQZX2.js";
9
+ } from "./chunk-2A5B7GWR.js";
7
10
  import {
8
- generateSecure
9
- } from "./chunk-NUDITUKX.js";
11
+ AURA_AUTH_VERSION
12
+ } from "./chunk-LX3TJ2TJ.js";
10
13
  import {
11
14
  OAuthProtocolError,
12
15
  isNativeError,
13
16
  isOAuthProtocolError
14
- } from "./chunk-RRLIF4PQ.js";
17
+ } from "./chunk-U5663F2U.js";
15
18
 
16
19
  // src/actions/callback/userinfo.ts
17
20
  var getDefaultUserInfo = (profile) => {
@@ -24,18 +27,23 @@ var getDefaultUserInfo = (profile) => {
24
27
  };
25
28
  };
26
29
  var getUserInfo = async (oauthConfig, accessToken, logger) => {
27
- const userinfoEndpoint = oauthConfig.userInfo;
30
+ const userInfoConfig = oauthConfig.userInfo;
31
+ const userinfoURL = typeof userInfoConfig === "string" ? userInfoConfig : userInfoConfig.url;
32
+ const extraHeaders = typeof userInfoConfig === "string" ? void 0 : userInfoConfig.headers;
33
+ const method = typeof userInfoConfig === "string" ? "GET" : (userInfoConfig.method ?? "GET").toUpperCase();
28
34
  try {
29
35
  logger?.log("OAUTH_USERINFO_REQUEST_INITIATED", {
30
36
  structuredData: {
31
- endpoint: userinfoEndpoint
37
+ endpoint: userinfoURL
32
38
  }
33
39
  });
34
- const response = await fetchAsync(userinfoEndpoint, {
35
- method: "GET",
40
+ const response = await fetchAsync(userinfoURL, {
41
+ method,
36
42
  headers: {
43
+ "User-Agent": `Aura Auth/${AURA_AUTH_VERSION}`,
37
44
  Accept: "application/json",
38
- Authorization: `Bearer ${accessToken}`
45
+ Authorization: `Bearer ${accessToken}`,
46
+ ...extraHeaders ?? {}
39
47
  }
40
48
  });
41
49
  if (!response.ok) {
@@ -0,0 +1,59 @@
1
+ import {
2
+ createAuthorizationURL
3
+ } from "./chunk-D2CSIUKP.js";
4
+ import {
5
+ createRedirectTo,
6
+ createRedirectURI,
7
+ createSignInURL,
8
+ getBaseURL
9
+ } from "./chunk-LATR3NIV.js";
10
+ import {
11
+ AuthInternalError
12
+ } from "./chunk-U5663F2U.js";
13
+ import {
14
+ cacheControl
15
+ } from "./chunk-EBAMFRB7.js";
16
+
17
+ // src/api/signIn.ts
18
+ import { HeadersBuilder } from "@aura-stack/router";
19
+ var signIn = async (oauth, {
20
+ ctx,
21
+ headers: headersInit,
22
+ redirectTo = "/",
23
+ redirect,
24
+ request: requestInit
25
+ }) => {
26
+ const headers = new Headers(headersInit);
27
+ const provider = ctx.oauth[oauth];
28
+ if (!provider) {
29
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", `The OAuth provider "${oauth}" is not configured.`);
30
+ }
31
+ let request = requestInit;
32
+ if (!request) {
33
+ const origin = await getBaseURL({ ctx, headers });
34
+ const url = `${origin}${ctx.basePath}/signIn/${oauth}`;
35
+ request = new Request(url, { headers });
36
+ }
37
+ if (redirect === false) {
38
+ const signInURL = await createSignInURL({ request, oauth, ctx, redirectTo });
39
+ return { redirect: false, signInURL };
40
+ }
41
+ const redirectURI = await createRedirectURI(request, oauth, ctx);
42
+ const redirectToValue = await createRedirectTo(request, redirectTo, ctx);
43
+ const { authorization, state, codeVerifier } = await createAuthorizationURL(provider, redirectURI, ctx);
44
+ ctx?.logger?.log("SIGN_IN_INITIATED", {
45
+ structuredData: { oauth_provider: oauth }
46
+ });
47
+ const headersList = new HeadersBuilder(cacheControl).setHeader("Location", authorization).setCookie(ctx.cookies.state.name, state, ctx.cookies.state.attributes).setCookie(ctx.cookies.redirectURI.name, redirectURI, ctx.cookies.redirectURI.attributes).setCookie(ctx.cookies.redirectTo.name, redirectToValue, ctx.cookies.redirectTo.attributes).setCookie(ctx.cookies.codeVerifier.name, codeVerifier, ctx.cookies.codeVerifier.attributes).toHeaders();
48
+ return Response.json(
49
+ { redirect: redirect ?? true, signInURL: authorization },
50
+ {
51
+ status: redirect ?? true ? 302 : 200,
52
+ headers: headersList
53
+ }
54
+ );
55
+ };
56
+
57
+ export {
58
+ signIn
59
+ };
@@ -0,0 +1,94 @@
1
+ import {
2
+ verifyCSRF
3
+ } from "./chunk-V6LLEAR4.js";
4
+ import {
5
+ getErrorName
6
+ } from "./chunk-LX3TJ2TJ.js";
7
+ import {
8
+ expiredCookieAttributes,
9
+ getCookie
10
+ } from "./chunk-XY5R3EHH.js";
11
+ import {
12
+ AuthSecurityError
13
+ } from "./chunk-U5663F2U.js";
14
+ import {
15
+ secureApiHeaders
16
+ } from "./chunk-EBAMFRB7.js";
17
+
18
+ // src/api/signOut.ts
19
+ import { HeadersBuilder } from "@aura-stack/router";
20
+ var signOut = async ({
21
+ ctx,
22
+ headers: headersInit,
23
+ redirectTo = "/",
24
+ skipCSRFCheck = false
25
+ }) => {
26
+ const headers = new Headers(headersInit);
27
+ const header = headers.get("X-CSRF-Token");
28
+ let session = null;
29
+ let csrfToken = null;
30
+ try {
31
+ session = getCookie(headers, ctx.cookies.sessionToken.name);
32
+ } catch {
33
+ throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
34
+ }
35
+ try {
36
+ csrfToken = getCookie(headers, ctx.cookies.csrfToken.name);
37
+ } catch {
38
+ throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
39
+ }
40
+ ctx?.logger?.log("SIGN_OUT_ATTEMPT", {
41
+ structuredData: {
42
+ has_session: Boolean(session),
43
+ has_csrf_token: Boolean(csrfToken),
44
+ has_csrf_header: Boolean(header),
45
+ skip_csrf_check: skipCSRFCheck
46
+ }
47
+ });
48
+ if (!session) {
49
+ ctx?.logger?.log("SESSION_TOKEN_MISSING");
50
+ throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
51
+ }
52
+ if (!skipCSRFCheck) {
53
+ if (!csrfToken) {
54
+ ctx?.logger?.log("CSRF_TOKEN_MISSING");
55
+ throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
56
+ }
57
+ if (!header) {
58
+ ctx?.logger?.log("CSRF_HEADER_MISSING");
59
+ throw new AuthSecurityError("CSRF_HEADER_MISSING", "The CSRF header is missing.");
60
+ }
61
+ try {
62
+ await verifyCSRF(ctx.jose, csrfToken, header);
63
+ } catch (error) {
64
+ ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
65
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
66
+ }
67
+ ctx?.logger?.log("SIGN_OUT_CSRF_VERIFIED");
68
+ } else {
69
+ try {
70
+ await ctx.jose.verifyJWS(csrfToken);
71
+ } catch (error) {
72
+ ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
73
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
74
+ }
75
+ }
76
+ try {
77
+ await ctx.jose.decodeJWT(session);
78
+ ctx?.logger?.log("SIGN_OUT_SUCCESS");
79
+ } catch (error) {
80
+ ctx?.logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
81
+ }
82
+ const headersList = new HeadersBuilder(secureApiHeaders).setHeader("Location", redirectTo).setCookie(ctx.cookies.csrfToken.name, "", expiredCookieAttributes).setCookie(ctx.cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
83
+ return Response.json(
84
+ { redirect: Boolean(redirectTo), url: redirectTo },
85
+ {
86
+ status: 202,
87
+ headers: headersList
88
+ }
89
+ );
90
+ };
91
+
92
+ export {
93
+ signOut
94
+ };