@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.
- package/dist/@types/index.d.ts +6 -2
- package/dist/@types/router.d.d.ts +6 -2
- package/dist/actions/callback/access-token.cjs +103 -59
- package/dist/actions/callback/access-token.d.ts +7 -3
- package/dist/actions/callback/access-token.js +3 -3
- package/dist/actions/callback/callback.cjs +200 -134
- package/dist/actions/callback/callback.d.ts +32 -3
- package/dist/actions/callback/callback.js +11 -12
- package/dist/actions/callback/userinfo.cjs +103 -70
- package/dist/actions/callback/userinfo.d.ts +6 -2
- package/dist/actions/callback/userinfo.js +7 -8
- package/dist/actions/csrfToken/csrfToken.cjs +7 -15
- package/dist/actions/csrfToken/csrfToken.d.ts +3 -1
- package/dist/actions/csrfToken/csrfToken.js +7 -8
- package/dist/actions/index.cjs +502 -295
- package/dist/actions/index.d.ts +5 -2
- package/dist/actions/index.js +23 -20
- package/dist/actions/session/session.cjs +76 -24
- package/dist/actions/session/session.d.ts +3 -1
- package/dist/actions/session/session.js +6 -4
- package/dist/actions/signIn/authorization-url.cjs +288 -0
- package/dist/actions/signIn/authorization-url.d.ts +31 -0
- package/dist/actions/signIn/authorization-url.js +16 -0
- package/dist/actions/signIn/authorization.cjs +91 -132
- package/dist/actions/signIn/authorization.d.ts +17 -16
- package/dist/actions/signIn/authorization.js +8 -7
- package/dist/actions/signIn/signIn.cjs +319 -191
- package/dist/actions/signIn/signIn.d.ts +32 -3
- package/dist/actions/signIn/signIn.js +10 -9
- package/dist/actions/signOut/signOut.cjs +211 -212
- package/dist/actions/signOut/signOut.d.ts +9 -1
- package/dist/actions/signOut/signOut.js +9 -10
- package/dist/api/createApi.cjs +750 -0
- package/dist/api/createApi.d.ts +12 -0
- package/dist/api/createApi.js +19 -0
- package/dist/api/getSession.cjs +141 -0
- package/dist/api/getSession.d.ts +16 -0
- package/dist/api/getSession.js +10 -0
- package/dist/api/signIn.cjs +549 -0
- package/dist/api/signIn.d.ts +26 -0
- package/dist/api/signIn.js +15 -0
- package/dist/api/signOut.cjs +279 -0
- package/dist/api/signOut.d.ts +16 -0
- package/dist/api/signOut.js +13 -0
- package/dist/assert.cjs +42 -9
- package/dist/assert.d.ts +8 -4
- package/dist/assert.js +5 -5
- package/dist/{chunk-KJBAQZX2.js → chunk-2A5B7GWR.js} +44 -11
- package/dist/chunk-2GQLSIJ2.js +40 -0
- package/dist/chunk-2IR674WX.js +44 -0
- package/dist/chunk-3J5TUH2I.js +50 -0
- package/dist/chunk-4RWSYUKX.js +98 -0
- package/dist/chunk-5X7JZMEF.js +0 -0
- package/dist/{chunk-TZB6MUXN.js → chunk-7BE46WWS.js} +21 -11
- package/dist/chunk-7YYXFKLR.js +35 -0
- package/dist/chunk-C3A37LQC.js +33 -0
- package/dist/chunk-CITNGXDA.js +31 -0
- package/dist/chunk-CWX724AG.js +78 -0
- package/dist/chunk-D2CSIUKP.js +74 -0
- package/dist/{chunk-ICAZ4OVS.js → chunk-FPCVZUVG.js} +2 -2
- package/dist/{chunk-XGLBNXL4.js → chunk-GNNBM2WJ.js} +17 -9
- package/dist/chunk-JOCGX3RP.js +59 -0
- package/dist/chunk-KBXWTD6E.js +94 -0
- package/dist/{chunk-XUP6KKNG.js → chunk-LATR3NIV.js} +48 -37
- package/dist/chunk-LAYPUDQF.js +39 -0
- package/dist/chunk-LX3TJ2TJ.js +294 -0
- package/dist/{chunk-6MXFPFR3.js → chunk-NHZBQNRR.js} +19 -19
- package/dist/{chunk-TM5IPSNF.js → chunk-PDP3PHB3.js} +33 -19
- package/dist/chunk-PHYNROD4.js +47 -0
- package/dist/chunk-QQEKY4XP.js +29 -0
- package/dist/{chunk-VNCNJKS2.js → chunk-U4RK4LKJ.js} +82 -1
- package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
- package/dist/chunk-UN7X6SU5.js +53 -0
- package/dist/chunk-UZQJJD6A.js +100 -0
- package/dist/{chunk-NUDITUKX.js → chunk-V6LLEAR4.js} +22 -15
- package/dist/{chunk-4MYWAOLG.js → chunk-WHNDRO3N.js} +20 -1
- package/dist/{chunk-5W4BRQYG.js → chunk-XY5R3EHH.js} +6 -3
- package/dist/client/client.cjs +135 -0
- package/dist/client/client.d.ts +85 -0
- package/dist/client/client.js +9 -0
- package/dist/client/index.cjs +135 -0
- package/dist/client/index.d.ts +14 -0
- package/dist/client/index.js +10 -0
- package/dist/context.cjs +1237 -0
- package/dist/context.d.ts +16 -0
- package/dist/context.js +28 -0
- package/dist/cookie.cjs +33 -2
- package/dist/cookie.d.ts +9 -5
- package/dist/cookie.js +3 -2
- package/dist/createAuth.cjs +2320 -0
- package/dist/createAuth.d.ts +12 -0
- package/dist/createAuth.js +48 -0
- package/dist/env.cjs +24 -2
- package/dist/env.d.ts +4 -1
- package/dist/env.js +9 -3
- package/dist/errors.cjs +17 -0
- package/dist/errors.d.ts +13 -3
- package/dist/errors.js +5 -1
- package/dist/{index-CSyIJmCM.d.ts → index-_aXtxb_s.d.ts} +383 -13
- package/dist/index.cjs +2135 -1547
- package/dist/index.d.ts +9 -30
- package/dist/index.js +46 -119
- package/dist/jose.cjs +52 -14
- package/dist/jose.d.ts +12 -25
- package/dist/jose.js +11 -3
- package/dist/logger.cjs +132 -0
- package/dist/logger.d.ts +6 -2
- package/dist/logger.js +10 -1
- package/dist/oauth/atlassian.cjs +57 -0
- package/dist/oauth/atlassian.d.ts +12 -0
- package/dist/oauth/atlassian.js +6 -0
- package/dist/oauth/bitbucket.d.ts +6 -2
- package/dist/oauth/discord.d.ts +6 -2
- package/dist/oauth/dropbox.cjs +53 -0
- package/dist/oauth/dropbox.d.ts +12 -0
- package/dist/oauth/dropbox.js +6 -0
- package/dist/oauth/figma.d.ts +6 -2
- package/dist/oauth/github.d.ts +6 -2
- package/dist/oauth/gitlab.d.ts +6 -2
- package/dist/oauth/index.cjs +278 -88
- package/dist/oauth/index.d.ts +6 -2
- package/dist/oauth/index.js +27 -11
- package/dist/oauth/mailchimp.d.ts +6 -2
- package/dist/oauth/notion.cjs +131 -0
- package/dist/oauth/notion.d.ts +12 -0
- package/dist/oauth/notion.js +9 -0
- package/dist/oauth/pinterest.d.ts +6 -2
- package/dist/oauth/spotify.d.ts +6 -2
- package/dist/oauth/strava.d.ts +6 -2
- package/dist/oauth/twitch.cjs +95 -0
- package/dist/oauth/twitch.d.ts +12 -0
- package/dist/oauth/twitch.js +7 -0
- package/dist/oauth/x.d.ts +6 -2
- package/dist/schemas.cjs +84 -51
- package/dist/schemas.d.ts +103 -23
- package/dist/schemas.js +1 -1
- package/dist/secure.cjs +36 -36
- package/dist/secure.d.ts +10 -4
- package/dist/secure.js +7 -6
- package/dist/utils.cjs +109 -3
- package/dist/utils.d.ts +15 -4
- package/dist/utils.js +11 -4
- package/package.json +9 -5
- package/dist/chunk-4EKY7655.js +0 -123
- package/dist/chunk-7QF22LHP.js +0 -67
- package/dist/chunk-ALG3GIV4.js +0 -95
- package/dist/chunk-FRJFWTOY.js +0 -70
- package/dist/chunk-PHFH2MGS.js +0 -36
- 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-
|
|
7
|
+
} from "./chunk-2A5B7GWR.js";
|
|
9
8
|
import {
|
|
10
9
|
AuthInternalError,
|
|
11
10
|
OAuthProtocolError
|
|
12
|
-
} from "./chunk-
|
|
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
|
|
17
|
-
if (!
|
|
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
|
|
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:
|
|
35
|
+
redirect_uri: redirectURI,
|
|
27
36
|
grant_type: "authorization_code"
|
|
28
37
|
}
|
|
29
38
|
});
|
|
30
|
-
const response = await fetchAsync(
|
|
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
|
|
40
|
-
redirect_uri:
|
|
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,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-
|
|
9
|
+
} from "./chunk-2A5B7GWR.js";
|
|
7
10
|
import {
|
|
8
|
-
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
AURA_AUTH_VERSION
|
|
12
|
+
} from "./chunk-LX3TJ2TJ.js";
|
|
10
13
|
import {
|
|
11
14
|
OAuthProtocolError,
|
|
12
15
|
isNativeError,
|
|
13
16
|
isOAuthProtocolError
|
|
14
|
-
} from "./chunk-
|
|
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
|
|
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:
|
|
37
|
+
endpoint: userinfoURL
|
|
32
38
|
}
|
|
33
39
|
});
|
|
34
|
-
const response = await fetchAsync(
|
|
35
|
-
method
|
|
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
|
+
};
|