@aura-stack/auth 0.1.0 → 0.2.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 +3 -4
- package/dist/@types/router.d.d.ts +3 -4
- package/dist/@types/utility.d.ts +1 -5
- package/dist/actions/callback/access-token.cjs +51 -41
- package/dist/actions/callback/access-token.d.ts +3 -4
- package/dist/actions/callback/access-token.js +4 -3
- package/dist/actions/callback/callback.cjs +115 -210
- package/dist/actions/callback/callback.d.ts +3 -4
- package/dist/actions/callback/callback.js +9 -10
- package/dist/actions/callback/userinfo.cjs +35 -22
- package/dist/actions/callback/userinfo.d.ts +3 -4
- package/dist/actions/callback/userinfo.js +6 -5
- package/dist/actions/csrfToken/csrfToken.cjs +34 -103
- package/dist/actions/csrfToken/csrfToken.js +6 -6
- package/dist/actions/index.cjs +234 -391
- package/dist/actions/index.d.ts +3 -4
- package/dist/actions/index.js +16 -17
- package/dist/actions/session/session.cjs +25 -109
- package/dist/actions/session/session.js +4 -5
- package/dist/actions/signIn/authorization.cjs +64 -55
- package/dist/actions/signIn/authorization.d.ts +3 -4
- package/dist/actions/signIn/authorization.js +5 -5
- package/dist/actions/signIn/signIn.cjs +84 -206
- package/dist/actions/signIn/signIn.d.ts +3 -4
- package/dist/actions/signIn/signIn.js +7 -9
- package/dist/actions/signOut/signOut.cjs +88 -234
- package/dist/actions/signOut/signOut.js +8 -9
- package/dist/assert.cjs +5 -0
- package/dist/assert.d.ts +9 -1
- package/dist/assert.js +3 -1
- package/dist/chunk-2RXNXMCZ.js +55 -0
- package/dist/{chunk-UJJ7R56J.js → chunk-4V4JNXVF.js} +13 -10
- package/dist/chunk-6R2YZ4AC.js +22 -0
- package/dist/{chunk-VFTYH33W.js → chunk-7H3OR6UU.js} +29 -9
- package/dist/{chunk-256KIVJL.js → chunk-CXLATHS5.js} +53 -9
- package/dist/{chunk-6SM22VVJ.js → chunk-EIL2FPSS.js} +5 -1
- package/dist/chunk-IMICRJ5U.js +197 -0
- package/dist/{chunk-EBPE35JT.js → chunk-IUYZQTJV.js} +0 -1
- package/dist/{chunk-GZU3RBTB.js → chunk-N2APGLXA.js} +19 -10
- package/dist/chunk-NEVKX6K2.js +70 -0
- package/dist/{chunk-XXJKNKGQ.js → chunk-PTJUYB33.js} +9 -13
- package/dist/chunk-QDO2KSRJ.js +35 -0
- package/dist/{chunk-CAKJT3KS.js → chunk-QEZL7EYN.js} +21 -17
- package/dist/chunk-RRLIF4PQ.js +55 -0
- package/dist/chunk-TLE4PXY3.js +39 -0
- package/dist/chunk-UEH3LVON.js +97 -0
- package/dist/{chunk-HMRKN75I.js → chunk-WD7AUHQ5.js} +12 -7
- package/dist/{chunk-RLT4RFKV.js → chunk-ZLR3LI6X.js} +19 -9
- package/dist/cookie.cjs +140 -99
- package/dist/cookie.d.ts +33 -43
- package/dist/cookie.js +10 -17
- package/dist/errors.cjs +85 -0
- package/dist/errors.d.ts +48 -0
- package/dist/errors.js +18 -0
- package/dist/{index-DpfbvTZ_.d.ts → index-EqsoyjrF.d.ts} +139 -57
- package/dist/index.cjs +427 -389
- package/dist/index.d.ts +4 -5
- package/dist/index.js +37 -26
- package/dist/jose.cjs +23 -12
- package/dist/jose.d.ts +4 -1
- package/dist/jose.js +5 -4
- package/dist/oauth/bitbucket.d.ts +3 -4
- package/dist/oauth/discord.cjs +0 -1
- package/dist/oauth/discord.d.ts +3 -4
- package/dist/oauth/discord.js +1 -1
- package/dist/oauth/figma.d.ts +3 -4
- package/dist/oauth/github.d.ts +3 -4
- package/dist/oauth/gitlab.d.ts +3 -4
- package/dist/oauth/index.cjs +132 -6
- package/dist/oauth/index.d.ts +3 -4
- package/dist/oauth/index.js +12 -5
- package/dist/oauth/spotify.d.ts +3 -4
- package/dist/{response.cjs → oauth/strava.cjs} +21 -9
- package/dist/oauth/strava.d.ts +6 -0
- package/dist/oauth/strava.js +6 -0
- package/dist/oauth/x.d.ts +3 -4
- package/dist/schemas.cjs +11 -5
- package/dist/schemas.d.ts +70 -67
- package/dist/schemas.js +3 -1
- package/dist/secure.cjs +27 -19
- package/dist/secure.d.ts +3 -4
- package/dist/secure.js +4 -3
- package/dist/utils.cjs +90 -15
- package/dist/utils.d.ts +11 -2
- package/dist/utils.js +8 -4
- package/package.json +5 -6
- package/dist/chunk-FJUDBLCP.js +0 -59
- package/dist/chunk-HGJ4TXY4.js +0 -137
- package/dist/chunk-JAPMIE6S.js +0 -10
- package/dist/chunk-LLR722CL.js +0 -96
- package/dist/chunk-SJPDVKUS.js +0 -112
- package/dist/chunk-SMQO5WD7.js +0 -30
- package/dist/chunk-UTDLUEEG.js +0 -31
- package/dist/chunk-ZV4BH47P.js +0 -154
- package/dist/error.cjs +0 -88
- package/dist/error.d.ts +0 -62
- package/dist/error.js +0 -16
- package/dist/response.d.ts +0 -10
- package/dist/response.js +0 -6
package/dist/@types/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import 'zod/v4';
|
|
2
|
-
import '@aura-stack/jose/jose';
|
|
3
2
|
import '../schemas.js';
|
|
4
|
-
import 'cookie';
|
|
3
|
+
import '@aura-stack/router/cookie';
|
|
4
|
+
import '@aura-stack/jose/jose';
|
|
5
|
+
export { i as APIErrorMap, V as AccessTokenError, d as AuthConfig, e as AuthInstance, b as AuthInternalErrorCode, A as AuthRuntimeConfig, c as AuthSecurityErrorCode, T as AuthorizationError, C as CookieConfig, P as CookieName, a as CookieStoreConfig, M as CookieStrategyAttributes, E as ErrorType, K as HostCookie, J as JWTPayloadWithToken, z as JWTStandardClaims, f as JoseInstance, Y as OAuthEnv, Q as OAuthError, O as OAuthProvider, g as OAuthProviderConfig, h as OAuthProviderCredentials, R as RouterGlobalContext, H as SecureCookie, S as Session, L as StandardCookie, W as TokenRevocationError, U as User } from '../index-EqsoyjrF.js';
|
|
5
6
|
export { LiteralUnion, Prettify } from './utility.js';
|
|
6
|
-
export { y as AccessTokenError, c as AuthConfig, d as AuthInstance, A as AuthRuntimeConfig, w as AuthorizationError, C as CookieConfig, a as CookieConfigInternal, b as CookieName, u as CookieStrategyOptions, E as ErrorType, H as HostCookie, q as JWTStandardClaims, J as JoseInstance, v as OAuthError, O as OAuthProvider, e as OAuthProviderConfig, f as OAuthProviderCredentials, R as RouterGlobalContext, r as SecureCookie, S as Session, t as StandardCookie, T as TokenRevocationError, U as User } from '../index-DpfbvTZ_.js';
|
|
7
|
-
import 'zod/v4/core';
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { R as RouterGlobalContext } from '../index-
|
|
1
|
+
import { R as RouterGlobalContext } from '../index-EqsoyjrF.js';
|
|
2
2
|
import 'zod/v4';
|
|
3
|
-
import '@aura-stack/jose/jose';
|
|
4
3
|
import '../schemas.js';
|
|
5
|
-
import '
|
|
6
|
-
import '
|
|
4
|
+
import '@aura-stack/router/cookie';
|
|
5
|
+
import '@aura-stack/jose/jose';
|
|
7
6
|
import './utility.js';
|
|
8
7
|
|
|
9
8
|
declare module "@aura-stack/router" {
|
package/dist/@types/utility.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
type Prettify<T> = {
|
|
2
2
|
[K in keyof T]: T[K];
|
|
3
|
-
} & {
|
|
4
|
-
__aura_auth_prettify_brand?: never;
|
|
5
|
-
};
|
|
6
|
-
type LiteralUnion<T extends U, U = string> = (T | (U & Record<never, never>)) & {
|
|
7
|
-
__aura_auth_literal_union_brand?: never;
|
|
8
3
|
};
|
|
4
|
+
type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>);
|
|
9
5
|
|
|
10
6
|
export type { LiteralUnion, Prettify };
|
|
@@ -24,52 +24,57 @@ __export(access_token_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(access_token_exports);
|
|
26
26
|
|
|
27
|
-
// src/
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
// src/utils.ts
|
|
28
|
+
var import_router = require("@aura-stack/router");
|
|
29
|
+
|
|
30
|
+
// src/errors.ts
|
|
31
|
+
var OAuthProtocolError = class extends Error {
|
|
32
|
+
type = "OAUTH_PROTOCOL_ERROR";
|
|
33
|
+
error;
|
|
34
|
+
errorURI;
|
|
35
|
+
constructor(error, description, errorURI, options2) {
|
|
36
|
+
super(description, options2);
|
|
37
|
+
this.error = error;
|
|
38
|
+
this.errorURI = errorURI;
|
|
39
|
+
this.name = new.target.name;
|
|
40
|
+
Error.captureStackTrace(this, new.target);
|
|
33
41
|
}
|
|
34
42
|
};
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
throw new AuthError("invalid_request", error.message ?? message);
|
|
43
|
+
var AuthInternalError = class extends Error {
|
|
44
|
+
type = "AUTH_INTERNAL_ERROR";
|
|
45
|
+
code;
|
|
46
|
+
constructor(code, message, options2) {
|
|
47
|
+
super(message, options2);
|
|
48
|
+
this.code = code;
|
|
49
|
+
this.name = new.target.name;
|
|
50
|
+
Error.captureStackTrace(this, new.target);
|
|
44
51
|
}
|
|
45
52
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
UNSUPPORTED_RESPONSE_TYPE: "unsupported_response_type",
|
|
52
|
-
INVALID_SCOPE: "invalid_scope",
|
|
53
|
-
SERVER_ERROR: "server_error",
|
|
54
|
-
TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
|
|
55
|
-
},
|
|
56
|
-
ACCESS_TOKEN: {
|
|
57
|
-
INVALID_REQUEST: "invalid_request",
|
|
58
|
-
INVALID_CLIENT: "invalid_client",
|
|
59
|
-
INVALID_GRANT: "invalid_grant",
|
|
60
|
-
UNAUTHORIZED_CLIENT: "unauthorized_client",
|
|
61
|
-
UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
|
|
62
|
-
INVALID_SCOPE: "invalid_scope"
|
|
53
|
+
|
|
54
|
+
// src/utils.ts
|
|
55
|
+
var formatZodError = (error) => {
|
|
56
|
+
if (!error.issues || error.issues.length === 0) {
|
|
57
|
+
return {};
|
|
63
58
|
}
|
|
59
|
+
return error.issues.reduce((previous, issue) => {
|
|
60
|
+
const key = issue.path.join(".");
|
|
61
|
+
return {
|
|
62
|
+
...previous,
|
|
63
|
+
[key]: {
|
|
64
|
+
code: issue.code,
|
|
65
|
+
message: issue.message
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}, {});
|
|
64
69
|
};
|
|
65
70
|
|
|
66
71
|
// src/schemas.ts
|
|
67
72
|
var import_v4 = require("zod/v4");
|
|
68
73
|
var OAuthProviderConfigSchema = (0, import_v4.object)({
|
|
69
|
-
authorizeURL: (0, import_v4.
|
|
70
|
-
accessToken: (0, import_v4.
|
|
74
|
+
authorizeURL: (0, import_v4.httpUrl)(),
|
|
75
|
+
accessToken: (0, import_v4.httpUrl)(),
|
|
71
76
|
scope: (0, import_v4.string)().optional(),
|
|
72
|
-
userInfo: (0, import_v4.
|
|
77
|
+
userInfo: (0, import_v4.httpUrl)(),
|
|
73
78
|
responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
|
|
74
79
|
clientId: (0, import_v4.string)(),
|
|
75
80
|
clientSecret: (0, import_v4.string)()
|
|
@@ -81,8 +86,8 @@ var OAuthAuthorization = OAuthProviderConfigSchema.extend({
|
|
|
81
86
|
codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
|
|
82
87
|
});
|
|
83
88
|
var OAuthAuthorizationResponse = (0, import_v4.object)({
|
|
84
|
-
state: (0, import_v4.string)(),
|
|
85
|
-
code: (0, import_v4.string)()
|
|
89
|
+
state: (0, import_v4.string)("Missing state parameter in the OAuth authorization response."),
|
|
90
|
+
code: (0, import_v4.string)("Missing code parameter in the OAuth authorization response.")
|
|
86
91
|
});
|
|
87
92
|
var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
|
|
88
93
|
error: (0, import_v4.enum)([
|
|
@@ -126,12 +131,17 @@ var OAuthErrorResponse = (0, import_v4.object)({
|
|
|
126
131
|
error: (0, import_v4.string)(),
|
|
127
132
|
error_description: (0, import_v4.string)().optional()
|
|
128
133
|
});
|
|
134
|
+
var OAuthEnvSchema = (0, import_v4.object)({
|
|
135
|
+
clientId: import_v4.z.string().min(1, "OAuth Client ID is required in the environment variables."),
|
|
136
|
+
clientSecret: import_v4.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
137
|
+
});
|
|
129
138
|
|
|
130
139
|
// src/actions/callback/access-token.ts
|
|
131
140
|
var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) => {
|
|
132
141
|
const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
|
|
133
142
|
if (!parsed.success) {
|
|
134
|
-
|
|
143
|
+
const msg = JSON.stringify(formatZodError(parsed.error), null, 2);
|
|
144
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", msg);
|
|
135
145
|
}
|
|
136
146
|
const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
|
|
137
147
|
try {
|
|
@@ -155,13 +165,13 @@ var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) =>
|
|
|
155
165
|
if (!token.success) {
|
|
156
166
|
const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json);
|
|
157
167
|
if (!success) {
|
|
158
|
-
throw new
|
|
168
|
+
throw new OAuthProtocolError("INVALID_REQUEST", "Invalid access token response format");
|
|
159
169
|
}
|
|
160
|
-
throw new
|
|
170
|
+
throw new OAuthProtocolError(data.error, data?.error_description ?? "Failed to retrieve access token");
|
|
161
171
|
}
|
|
162
172
|
return token.data;
|
|
163
173
|
} catch (error) {
|
|
164
|
-
throw
|
|
174
|
+
throw error;
|
|
165
175
|
}
|
|
166
176
|
};
|
|
167
177
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { h as OAuthProviderCredentials } from '../../index-EqsoyjrF.js';
|
|
2
2
|
import 'zod/v4';
|
|
3
|
-
import '@aura-stack/jose/jose';
|
|
4
3
|
import '../../schemas.js';
|
|
5
|
-
import '
|
|
6
|
-
import '
|
|
4
|
+
import '@aura-stack/router/cookie';
|
|
5
|
+
import '@aura-stack/jose/jose';
|
|
7
6
|
import '../../@types/utility.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createAccessToken
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-4V4JNXVF.js";
|
|
4
|
+
import "../../chunk-WD7AUHQ5.js";
|
|
5
|
+
import "../../chunk-CXLATHS5.js";
|
|
6
|
+
import "../../chunk-RRLIF4PQ.js";
|
|
6
7
|
export {
|
|
7
8
|
createAccessToken
|
|
8
9
|
};
|
|
@@ -42,53 +42,54 @@ var import_node_crypto = __toESM(require("crypto"), 1);
|
|
|
42
42
|
// src/utils.ts
|
|
43
43
|
var import_router = require("@aura-stack/router");
|
|
44
44
|
|
|
45
|
-
// src/
|
|
46
|
-
var
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
// src/errors.ts
|
|
46
|
+
var OAuthProtocolError = class extends Error {
|
|
47
|
+
type = "OAUTH_PROTOCOL_ERROR";
|
|
48
|
+
error;
|
|
49
|
+
errorURI;
|
|
50
|
+
constructor(error, description, errorURI, options2) {
|
|
51
|
+
super(description, options2);
|
|
52
|
+
this.error = error;
|
|
53
|
+
this.errorURI = errorURI;
|
|
54
|
+
this.name = new.target.name;
|
|
55
|
+
Error.captureStackTrace(this, new.target);
|
|
51
56
|
}
|
|
52
57
|
};
|
|
53
|
-
var
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
throw new AuthError("invalid_request", error.message ?? message);
|
|
58
|
+
var AuthInternalError = class extends Error {
|
|
59
|
+
type = "AUTH_INTERNAL_ERROR";
|
|
60
|
+
code;
|
|
61
|
+
constructor(code, message, options2) {
|
|
62
|
+
super(message, options2);
|
|
63
|
+
this.code = code;
|
|
64
|
+
this.name = new.target.name;
|
|
65
|
+
Error.captureStackTrace(this, new.target);
|
|
62
66
|
}
|
|
63
67
|
};
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
|
|
73
|
-
},
|
|
74
|
-
ACCESS_TOKEN: {
|
|
75
|
-
INVALID_REQUEST: "invalid_request",
|
|
76
|
-
INVALID_CLIENT: "invalid_client",
|
|
77
|
-
INVALID_GRANT: "invalid_grant",
|
|
78
|
-
UNAUTHORIZED_CLIENT: "unauthorized_client",
|
|
79
|
-
UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
|
|
80
|
-
INVALID_SCOPE: "invalid_scope"
|
|
68
|
+
var AuthSecurityError = class extends Error {
|
|
69
|
+
type = "AUTH_SECURITY_ERROR";
|
|
70
|
+
code;
|
|
71
|
+
constructor(code, message, options2) {
|
|
72
|
+
super(message, options2);
|
|
73
|
+
this.code = code;
|
|
74
|
+
this.name = new.target.name;
|
|
75
|
+
Error.captureStackTrace(this, new.target);
|
|
81
76
|
}
|
|
82
77
|
};
|
|
78
|
+
var isNativeError = (error) => {
|
|
79
|
+
return error instanceof Error;
|
|
80
|
+
};
|
|
81
|
+
var isOAuthProtocolError = (error) => {
|
|
82
|
+
return error instanceof OAuthProtocolError;
|
|
83
|
+
};
|
|
83
84
|
|
|
84
85
|
// src/utils.ts
|
|
85
86
|
var equals = (a, b) => {
|
|
86
87
|
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
87
88
|
return a === b;
|
|
88
89
|
};
|
|
89
|
-
var sanitizeURL = (
|
|
90
|
+
var sanitizeURL = (url) => {
|
|
90
91
|
try {
|
|
91
|
-
let decodedURL = decodeURIComponent(
|
|
92
|
+
let decodedURL = decodeURIComponent(url).trim();
|
|
92
93
|
const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
|
|
93
94
|
let protocol = "";
|
|
94
95
|
let rest = decodedURL;
|
|
@@ -116,7 +117,7 @@ var sanitizeURL = (url2) => {
|
|
|
116
117
|
}
|
|
117
118
|
return sanitized;
|
|
118
119
|
} catch {
|
|
119
|
-
return
|
|
120
|
+
return url.trim();
|
|
120
121
|
}
|
|
121
122
|
};
|
|
122
123
|
var isValidRelativePath = (path) => {
|
|
@@ -127,6 +128,21 @@ var isValidRelativePath = (path) => {
|
|
|
127
128
|
if (sanitized.includes("..")) return false;
|
|
128
129
|
return true;
|
|
129
130
|
};
|
|
131
|
+
var formatZodError = (error) => {
|
|
132
|
+
if (!error.issues || error.issues.length === 0) {
|
|
133
|
+
return {};
|
|
134
|
+
}
|
|
135
|
+
return error.issues.reduce((previous, issue) => {
|
|
136
|
+
const key = issue.path.join(".");
|
|
137
|
+
return {
|
|
138
|
+
...previous,
|
|
139
|
+
[key]: {
|
|
140
|
+
code: issue.code,
|
|
141
|
+
message: issue.message
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}, {});
|
|
145
|
+
};
|
|
130
146
|
|
|
131
147
|
// src/secure.ts
|
|
132
148
|
var generateSecure = (length = 32) => {
|
|
@@ -157,10 +173,10 @@ var cacheControl = {
|
|
|
157
173
|
// src/schemas.ts
|
|
158
174
|
var import_v4 = require("zod/v4");
|
|
159
175
|
var OAuthProviderConfigSchema = (0, import_v4.object)({
|
|
160
|
-
authorizeURL: (0, import_v4.
|
|
161
|
-
accessToken: (0, import_v4.
|
|
176
|
+
authorizeURL: (0, import_v4.httpUrl)(),
|
|
177
|
+
accessToken: (0, import_v4.httpUrl)(),
|
|
162
178
|
scope: (0, import_v4.string)().optional(),
|
|
163
|
-
userInfo: (0, import_v4.
|
|
179
|
+
userInfo: (0, import_v4.httpUrl)(),
|
|
164
180
|
responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
|
|
165
181
|
clientId: (0, import_v4.string)(),
|
|
166
182
|
clientSecret: (0, import_v4.string)()
|
|
@@ -172,8 +188,8 @@ var OAuthAuthorization = OAuthProviderConfigSchema.extend({
|
|
|
172
188
|
codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
|
|
173
189
|
});
|
|
174
190
|
var OAuthAuthorizationResponse = (0, import_v4.object)({
|
|
175
|
-
state: (0, import_v4.string)(),
|
|
176
|
-
code: (0, import_v4.string)()
|
|
191
|
+
state: (0, import_v4.string)("Missing state parameter in the OAuth authorization response."),
|
|
192
|
+
code: (0, import_v4.string)("Missing code parameter in the OAuth authorization response.")
|
|
177
193
|
});
|
|
178
194
|
var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
|
|
179
195
|
error: (0, import_v4.enum)([
|
|
@@ -217,6 +233,10 @@ var OAuthErrorResponse = (0, import_v4.object)({
|
|
|
217
233
|
error: (0, import_v4.string)(),
|
|
218
234
|
error_description: (0, import_v4.string)().optional()
|
|
219
235
|
});
|
|
236
|
+
var OAuthEnvSchema = (0, import_v4.object)({
|
|
237
|
+
clientId: import_v4.z.string().min(1, "OAuth Client ID is required in the environment variables."),
|
|
238
|
+
clientSecret: import_v4.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
239
|
+
});
|
|
220
240
|
|
|
221
241
|
// src/actions/callback/userinfo.ts
|
|
222
242
|
var getDefaultUserInfo = (profile) => {
|
|
@@ -241,18 +261,20 @@ var getUserInfo = async (oauthConfig, accessToken) => {
|
|
|
241
261
|
const json = await response.json();
|
|
242
262
|
const { success, data } = OAuthErrorResponse.safeParse(json);
|
|
243
263
|
if (success) {
|
|
244
|
-
throw new
|
|
264
|
+
throw new OAuthProtocolError(
|
|
265
|
+
data.error,
|
|
266
|
+
data?.error_description ?? "An error occurred while fetching user information."
|
|
267
|
+
);
|
|
245
268
|
}
|
|
246
269
|
return oauthConfig?.profile ? oauthConfig.profile(json) : getDefaultUserInfo(json);
|
|
247
270
|
} catch (error) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return Response.json(body, init);
|
|
271
|
+
if (isOAuthProtocolError(error)) {
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
if (isNativeError(error)) {
|
|
275
|
+
throw new OAuthProtocolError("invalid_request", error.message, "", { cause: error });
|
|
276
|
+
}
|
|
277
|
+
throw new OAuthProtocolError("invalid_request", "Failed to fetch user information.", "", { cause: error });
|
|
256
278
|
}
|
|
257
279
|
};
|
|
258
280
|
|
|
@@ -260,7 +282,8 @@ var AuraResponse = class extends Response {
|
|
|
260
282
|
var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) => {
|
|
261
283
|
const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
|
|
262
284
|
if (!parsed.success) {
|
|
263
|
-
|
|
285
|
+
const msg = JSON.stringify(formatZodError(parsed.error), null, 2);
|
|
286
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", msg);
|
|
264
287
|
}
|
|
265
288
|
const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
|
|
266
289
|
try {
|
|
@@ -284,137 +307,53 @@ var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) =>
|
|
|
284
307
|
if (!token.success) {
|
|
285
308
|
const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json);
|
|
286
309
|
if (!success) {
|
|
287
|
-
throw new
|
|
310
|
+
throw new OAuthProtocolError("INVALID_REQUEST", "Invalid access token response format");
|
|
288
311
|
}
|
|
289
|
-
throw new
|
|
312
|
+
throw new OAuthProtocolError(data.error, data?.error_description ?? "Failed to retrieve access token");
|
|
290
313
|
}
|
|
291
314
|
return token.data;
|
|
292
315
|
} catch (error) {
|
|
293
|
-
throw
|
|
316
|
+
throw error;
|
|
294
317
|
}
|
|
295
318
|
};
|
|
296
319
|
|
|
297
320
|
// src/cookie.ts
|
|
298
|
-
var import_cookie = require("cookie");
|
|
299
|
-
|
|
300
|
-
// src/assert.ts
|
|
301
|
-
var isRequest = (value) => {
|
|
302
|
-
return typeof Request !== "undefined" && value instanceof Request;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// src/cookie.ts
|
|
306
|
-
var import_cookie2 = require("cookie");
|
|
307
|
-
var COOKIE_NAME = "aura-auth";
|
|
321
|
+
var import_cookie = require("@aura-stack/router/cookie");
|
|
308
322
|
var defaultCookieOptions = {
|
|
309
323
|
httpOnly: true,
|
|
310
324
|
sameSite: "lax",
|
|
311
325
|
path: "/",
|
|
312
326
|
maxAge: 60 * 60 * 24 * 15
|
|
313
327
|
};
|
|
314
|
-
var
|
|
315
|
-
secure: false,
|
|
328
|
+
var oauthCookieOptions = {
|
|
316
329
|
httpOnly: true,
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
secure: true,
|
|
321
|
-
prefix: "__Secure-"
|
|
322
|
-
};
|
|
323
|
-
var defaultHostCookieConfig = {
|
|
324
|
-
secure: true,
|
|
325
|
-
prefix: "__Host-",
|
|
326
|
-
path: "/",
|
|
327
|
-
domain: void 0
|
|
330
|
+
maxAge: 5 * 60,
|
|
331
|
+
sameSite: "lax",
|
|
332
|
+
expires: new Date(Date.now() + 5 * 60 * 1e3)
|
|
328
333
|
};
|
|
329
|
-
var
|
|
334
|
+
var expiredCookieAttributes = {
|
|
330
335
|
...defaultCookieOptions,
|
|
331
336
|
expires: /* @__PURE__ */ new Date(0),
|
|
332
337
|
maxAge: 0
|
|
333
338
|
};
|
|
334
|
-
var
|
|
335
|
-
|
|
336
|
-
name: options2?.name ?? COOKIE_NAME,
|
|
337
|
-
prefix: options2?.prefix ?? (options2?.secure ? "__Secure-" : ""),
|
|
338
|
-
...defaultCookieOptions,
|
|
339
|
-
...options2
|
|
340
|
-
};
|
|
341
|
-
};
|
|
342
|
-
var setCookie = (cookieName, value, options2) => {
|
|
343
|
-
const { prefix, name } = defineDefaultCookieOptions(options2);
|
|
344
|
-
const cookieNameWithPrefix = `${prefix}${name}.${cookieName}`;
|
|
345
|
-
return (0, import_cookie.serialize)(cookieNameWithPrefix, value, {
|
|
346
|
-
...defaultCookieOptions,
|
|
347
|
-
...options2
|
|
348
|
-
});
|
|
349
|
-
};
|
|
350
|
-
var getCookie = (petition, cookie, options2, optional = false) => {
|
|
351
|
-
const cookies = isRequest(petition) ? petition.headers.get("Cookie") : petition.headers.getSetCookie().join("; ");
|
|
339
|
+
var getCookie = (request, cookieName) => {
|
|
340
|
+
const cookies = request.headers.get("Cookie");
|
|
352
341
|
if (!cookies) {
|
|
353
|
-
|
|
354
|
-
return "";
|
|
355
|
-
}
|
|
356
|
-
throw new AuthError("invalid_request", "No cookies found. There is no active session");
|
|
342
|
+
throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
|
|
357
343
|
}
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (value === void 0) {
|
|
362
|
-
if (optional) {
|
|
363
|
-
return "";
|
|
364
|
-
}
|
|
365
|
-
throw new AuthError("invalid_request", `Cookie "${cookie}" not found. There is no active session`);
|
|
344
|
+
const value = (0, import_cookie.parse)(cookies)[cookieName];
|
|
345
|
+
if (!value) {
|
|
346
|
+
throw new AuthInternalError("COOKIE_NOT_FOUND", `Cookie "${cookieName}" not found. There is no active session`);
|
|
366
347
|
}
|
|
367
348
|
return value;
|
|
368
349
|
};
|
|
369
|
-
var createSessionCookie = async (
|
|
350
|
+
var createSessionCookie = async (jose, session) => {
|
|
370
351
|
try {
|
|
371
352
|
const encoded = await jose.encodeJWT(session);
|
|
372
|
-
return
|
|
353
|
+
return encoded;
|
|
373
354
|
} catch (error) {
|
|
374
|
-
throw new
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
var secureCookieOptions = (request, cookieOptions, trustedProxyHeaders) => {
|
|
378
|
-
const name = cookieOptions.name ?? COOKIE_NAME;
|
|
379
|
-
const isSecure = trustedProxyHeaders ? request.url.startsWith("https://") || request.headers.get("X-Forwarded-Proto") === "https" || request.headers.get("Forwarded")?.includes("proto=https") : request.url.startsWith("https://");
|
|
380
|
-
if (!cookieOptions.options?.httpOnly) {
|
|
381
|
-
console.warn(
|
|
382
|
-
"[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
if (cookieOptions.options?.domain === "*") {
|
|
386
|
-
console.warn("[WARNING]: Cookie 'Domain' is set to '*', which is insecure. Avoid wildcard domains.");
|
|
355
|
+
throw new AuthInternalError("INVALID_JWT_TOKEN", "Failed to create session cookie", { cause: error });
|
|
387
356
|
}
|
|
388
|
-
if (!isSecure) {
|
|
389
|
-
const options2 = cookieOptions.options;
|
|
390
|
-
if (options2?.secure) {
|
|
391
|
-
console.warn(
|
|
392
|
-
"[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
if (options2?.sameSite == "none") {
|
|
396
|
-
console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.");
|
|
397
|
-
}
|
|
398
|
-
if (process.env.NODE_ENV === "production") {
|
|
399
|
-
console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.");
|
|
400
|
-
}
|
|
401
|
-
return {
|
|
402
|
-
...defaultCookieOptions,
|
|
403
|
-
...cookieOptions.options,
|
|
404
|
-
sameSite: options2?.sameSite === "none" ? "lax" : options2?.sameSite ?? "lax",
|
|
405
|
-
...defaultStandardCookieConfig,
|
|
406
|
-
name
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
return cookieOptions.strategy === "host" ? {
|
|
410
|
-
...defaultCookieOptions,
|
|
411
|
-
...cookieOptions.options,
|
|
412
|
-
...defaultHostCookieConfig,
|
|
413
|
-
name
|
|
414
|
-
} : { ...defaultCookieOptions, ...cookieOptions.options, ...defaultSecureCookieConfig, name };
|
|
415
|
-
};
|
|
416
|
-
var expireCookie = (name, options2) => {
|
|
417
|
-
return setCookie(name, "", { ...options2, ...expiredCookieOptions });
|
|
418
357
|
};
|
|
419
358
|
|
|
420
359
|
// src/actions/callback/callback.ts
|
|
@@ -423,7 +362,7 @@ var callbackConfig = (oauth) => {
|
|
|
423
362
|
schemas: {
|
|
424
363
|
searchParams: OAuthAuthorizationResponse,
|
|
425
364
|
params: import_zod.default.object({
|
|
426
|
-
oauth: import_zod.default.enum(Object.keys(oauth))
|
|
365
|
+
oauth: import_zod.default.enum(Object.keys(oauth), "The OAuth provider is not supported or invalid.")
|
|
427
366
|
})
|
|
428
367
|
},
|
|
429
368
|
middlewares: [
|
|
@@ -431,7 +370,7 @@ var callbackConfig = (oauth) => {
|
|
|
431
370
|
const response = OAuthAuthorizationErrorResponse.safeParse(ctx.searchParams);
|
|
432
371
|
if (response.success) {
|
|
433
372
|
const { error, error_description } = response.data;
|
|
434
|
-
throw new
|
|
373
|
+
throw new OAuthProtocolError(error, error_description ?? "OAuth Authorization Error");
|
|
435
374
|
}
|
|
436
375
|
return ctx;
|
|
437
376
|
}
|
|
@@ -447,66 +386,32 @@ var callbackAction = (oauth) => {
|
|
|
447
386
|
request,
|
|
448
387
|
params: { oauth: oauth2 },
|
|
449
388
|
searchParams: { code, state },
|
|
450
|
-
context: { oauth: providers, cookies, jose
|
|
389
|
+
context: { oauth: providers, cookies, jose }
|
|
451
390
|
} = ctx;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
|
|
463
|
-
const sanitized = sanitizeURL(cookieRedirectTo);
|
|
464
|
-
if (!isValidRelativePath(sanitized)) {
|
|
465
|
-
throw new AuthError(
|
|
466
|
-
ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST,
|
|
467
|
-
"Invalid redirect path. Potential open redirect attack detected."
|
|
468
|
-
);
|
|
469
|
-
}
|
|
470
|
-
const headers = new Headers(cacheControl);
|
|
471
|
-
headers.set("Location", sanitized);
|
|
472
|
-
const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
|
|
473
|
-
const sessionCookie = await createSessionCookie(userInfo, cookieOptions, jose);
|
|
474
|
-
const csrfToken = await createCSRF(jose);
|
|
475
|
-
const csrfCookie = setCookie(
|
|
476
|
-
"csrfToken",
|
|
477
|
-
csrfToken,
|
|
478
|
-
secureCookieOptions(
|
|
479
|
-
request,
|
|
480
|
-
{
|
|
481
|
-
...cookies,
|
|
482
|
-
strategy: "host"
|
|
483
|
-
},
|
|
484
|
-
trustedProxyHeaders
|
|
485
|
-
)
|
|
391
|
+
const oauthConfig = providers[oauth2];
|
|
392
|
+
const cookieState = getCookie(request, cookies.state.name);
|
|
393
|
+
const cookieRedirectTo = getCookie(request, cookies.redirect_to.name);
|
|
394
|
+
const cookieRedirectURI = getCookie(request, cookies.redirect_uri.name);
|
|
395
|
+
const codeVerifier = getCookie(request, cookies.code_verifier.name);
|
|
396
|
+
if (!equals(cookieState, state)) {
|
|
397
|
+
throw new AuthSecurityError(
|
|
398
|
+
"MISMATCHING_STATE",
|
|
399
|
+
"The provided state passed in the OAuth response does not match the stored state."
|
|
486
400
|
);
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
} catch (error) {
|
|
495
|
-
if (isAuthError(error)) {
|
|
496
|
-
const { type, message } = error;
|
|
497
|
-
return AuraResponse.json(
|
|
498
|
-
{ error: type, error_description: message },
|
|
499
|
-
{ status: import_router2.statusCode.BAD_REQUEST }
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
return AuraResponse.json(
|
|
503
|
-
{
|
|
504
|
-
error: ERROR_RESPONSE.ACCESS_TOKEN.INVALID_CLIENT,
|
|
505
|
-
error_description: "An unexpected error occurred"
|
|
506
|
-
},
|
|
507
|
-
{ status: import_router2.statusCode.INTERNAL_SERVER_ERROR }
|
|
401
|
+
}
|
|
402
|
+
const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
|
|
403
|
+
const sanitized = sanitizeURL(cookieRedirectTo);
|
|
404
|
+
if (!isValidRelativePath(sanitized)) {
|
|
405
|
+
throw new AuthSecurityError(
|
|
406
|
+
"POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED",
|
|
407
|
+
"Invalid redirect path. Potential open redirect attack detected."
|
|
508
408
|
);
|
|
509
409
|
}
|
|
410
|
+
const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
|
|
411
|
+
const sessionCookie = await createSessionCookie(jose, userInfo);
|
|
412
|
+
const csrfToken = await createCSRF(jose);
|
|
413
|
+
const headers = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", sanitized).setCookie(cookies.sessionToken.name, sessionCookie, cookies.sessionToken.attributes).setCookie(cookies.csrfToken.name, csrfToken, cookies.csrfToken.attributes).setCookie(cookies.state.name, "", expiredCookieAttributes).setCookie(cookies.redirect_uri.name, "", expiredCookieAttributes).setCookie(cookies.redirect_to.name, "", expiredCookieAttributes).setCookie(cookies.code_verifier.name, "", expiredCookieAttributes).toHeaders();
|
|
414
|
+
return Response.json({ oauth: oauth2 }, { status: 302, headers });
|
|
510
415
|
},
|
|
511
416
|
callbackConfig(oauth)
|
|
512
417
|
);
|