@supabase/server 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +305 -0
- package/dist/adapters/hono/index.cjs +24 -0
- package/dist/adapters/hono/index.d.cts +11 -0
- package/dist/adapters/hono/index.d.mts +11 -0
- package/dist/adapters/hono/index.mjs +23 -0
- package/dist/core/index.cjs +9 -0
- package/dist/core/index.d.cts +3 -0
- package/dist/core/index.d.mts +3 -0
- package/dist/core/index.mjs +3 -0
- package/dist/create-admin-client-BZ_3qcxI.d.cts +60 -0
- package/dist/create-admin-client-CSX-Q_Fv.d.mts +60 -0
- package/dist/create-supabase-context-BrSIe29v.mjs +35 -0
- package/dist/create-supabase-context-DNWor6i_.cjs +40 -0
- package/dist/index.cjs +52 -0
- package/dist/index.d.cts +16 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +42 -0
- package/dist/types-BLM5-qA8.d.mts +59 -0
- package/dist/types-DNh3Z1O1.d.cts +59 -0
- package/dist/verify-auth-6a1UPrFz.cjs +317 -0
- package/dist/verify-auth-DxUT0XoT.mjs +270 -0
- package/dist/wrappers/index.cjs +26 -0
- package/dist/wrappers/index.d.cts +4 -0
- package/dist/wrappers/index.d.mts +4 -0
- package/dist/wrappers/index.mjs +24 -0
- package/package.json +99 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { a as JWTClaims, c as UserClaims, i as Credentials, l as WithSupabaseConfig, n as AllowWithKey, o as SupabaseContext, r as AuthResult, s as SupabaseEnv, t as Allow } from "./types-DNh3Z1O1.cjs";
|
|
2
|
+
import { a as extractCredentials, c as EnvError, i as verifyCredentials, n as createContextClient, o as resolveEnv, r as verifyAuth, s as AuthError, t as createAdminClient } from "./create-admin-client-BZ_3qcxI.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/with-supabase.d.ts
|
|
5
|
+
declare function withSupabase(config: WithSupabaseConfig, handler: (req: Request, ctx: SupabaseContext) => Promise<Response>): (req: Request) => Promise<Response>;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/create-supabase-context.d.ts
|
|
8
|
+
declare function createSupabaseContext(request: Request, options?: WithSupabaseConfig): Promise<{
|
|
9
|
+
data: SupabaseContext;
|
|
10
|
+
error: null;
|
|
11
|
+
} | {
|
|
12
|
+
data: null;
|
|
13
|
+
error: AuthError;
|
|
14
|
+
}>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { type Allow, type AllowWithKey, AuthError, type AuthResult, type Credentials, EnvError, type JWTClaims, type SupabaseContext, type SupabaseEnv, type UserClaims, type WithSupabaseConfig, createAdminClient, createContextClient, createSupabaseContext, extractCredentials, resolveEnv, verifyAuth, verifyCredentials, withSupabase };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { a as JWTClaims, c as UserClaims, i as Credentials, l as WithSupabaseConfig, n as AllowWithKey, o as SupabaseContext, r as AuthResult, s as SupabaseEnv, t as Allow } from "./types-BLM5-qA8.mjs";
|
|
2
|
+
import { a as extractCredentials, c as EnvError, i as verifyCredentials, n as createContextClient, o as resolveEnv, r as verifyAuth, s as AuthError, t as createAdminClient } from "./create-admin-client-CSX-Q_Fv.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/with-supabase.d.ts
|
|
5
|
+
declare function withSupabase(config: WithSupabaseConfig, handler: (req: Request, ctx: SupabaseContext) => Promise<Response>): (req: Request) => Promise<Response>;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/create-supabase-context.d.ts
|
|
8
|
+
declare function createSupabaseContext(request: Request, options?: WithSupabaseConfig): Promise<{
|
|
9
|
+
data: SupabaseContext;
|
|
10
|
+
error: null;
|
|
11
|
+
} | {
|
|
12
|
+
data: null;
|
|
13
|
+
error: AuthError;
|
|
14
|
+
}>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { type Allow, type AllowWithKey, AuthError, type AuthResult, type Credentials, EnvError, type JWTClaims, type SupabaseContext, type SupabaseEnv, type UserClaims, type WithSupabaseConfig, createAdminClient, createContextClient, createSupabaseContext, extractCredentials, resolveEnv, verifyAuth, verifyCredentials, withSupabase };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { a as createAdminClient, c as EnvError, i as createContextClient, n as verifyCredentials, o as resolveEnv, r as extractCredentials, s as AuthError, t as verifyAuth } from "./verify-auth-DxUT0XoT.mjs";
|
|
2
|
+
import { t as createSupabaseContext } from "./create-supabase-context-BrSIe29v.mjs";
|
|
3
|
+
import { corsHeaders } from "@supabase/supabase-js/cors";
|
|
4
|
+
|
|
5
|
+
//#region src/cors.ts
|
|
6
|
+
function buildCorsHeaders(config) {
|
|
7
|
+
if (config === false) return {};
|
|
8
|
+
if (typeof config === "object") return config;
|
|
9
|
+
return corsHeaders;
|
|
10
|
+
}
|
|
11
|
+
function addCorsHeaders(response, config) {
|
|
12
|
+
if (config === false) return response;
|
|
13
|
+
const corsHeaders = buildCorsHeaders(config);
|
|
14
|
+
const newResponse = new Response(response.body, response);
|
|
15
|
+
for (const [key, value] of Object.entries(corsHeaders)) newResponse.headers.set(key, value);
|
|
16
|
+
return newResponse;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/with-supabase.ts
|
|
21
|
+
function withSupabase(config, handler) {
|
|
22
|
+
return async (req) => {
|
|
23
|
+
if (config.cors !== false && req.method === "OPTIONS") return new Response(null, {
|
|
24
|
+
status: 204,
|
|
25
|
+
headers: buildCorsHeaders(config.cors)
|
|
26
|
+
});
|
|
27
|
+
const { data: ctx, error } = await createSupabaseContext(req, config);
|
|
28
|
+
if (error) return Response.json({
|
|
29
|
+
error: error.message,
|
|
30
|
+
code: error.code
|
|
31
|
+
}, {
|
|
32
|
+
status: error.status,
|
|
33
|
+
headers: config.cors !== false ? buildCorsHeaders(config.cors) : {}
|
|
34
|
+
});
|
|
35
|
+
const response = await handler(req, ctx);
|
|
36
|
+
if (config.cors !== false) return addCorsHeaders(response, config.cors);
|
|
37
|
+
return response;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { AuthError, EnvError, createAdminClient, createContextClient, createSupabaseContext, extractCredentials, resolveEnv, verifyAuth, verifyCredentials, withSupabase };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
type Allow = 'always' | 'public' | 'secret' | 'user';
|
|
5
|
+
type AllowWithKey = Allow | `public:${string}` | `secret:${string}`;
|
|
6
|
+
interface SupabaseEnv {
|
|
7
|
+
url: string;
|
|
8
|
+
publishableKeys: Record<string, string>;
|
|
9
|
+
secretKeys: Record<string, string>;
|
|
10
|
+
jwks: JsonWebKeySet | null;
|
|
11
|
+
}
|
|
12
|
+
interface JsonWebKeySet {
|
|
13
|
+
keys: JsonWebKey[];
|
|
14
|
+
}
|
|
15
|
+
interface Credentials {
|
|
16
|
+
token: string | null;
|
|
17
|
+
apikey: string | null;
|
|
18
|
+
}
|
|
19
|
+
interface AuthResult {
|
|
20
|
+
authType: Allow;
|
|
21
|
+
token: string | null;
|
|
22
|
+
userClaims: UserClaims | null;
|
|
23
|
+
claims: JWTClaims | null;
|
|
24
|
+
keyName?: string | null;
|
|
25
|
+
}
|
|
26
|
+
interface JWTClaims {
|
|
27
|
+
sub: string;
|
|
28
|
+
iss?: string;
|
|
29
|
+
aud?: string | string[];
|
|
30
|
+
exp?: number;
|
|
31
|
+
iat?: number;
|
|
32
|
+
role?: string;
|
|
33
|
+
email?: string;
|
|
34
|
+
app_metadata?: Record<string, unknown>;
|
|
35
|
+
user_metadata?: Record<string, unknown>;
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
interface UserClaims {
|
|
39
|
+
id: string;
|
|
40
|
+
role?: string;
|
|
41
|
+
email?: string;
|
|
42
|
+
appMetadata?: Record<string, unknown>;
|
|
43
|
+
userMetadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
interface WithSupabaseConfig {
|
|
46
|
+
allow?: AllowWithKey | AllowWithKey[];
|
|
47
|
+
env?: Partial<SupabaseEnv>;
|
|
48
|
+
cors?: boolean | Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
interface SupabaseContext {
|
|
51
|
+
supabase: SupabaseClient;
|
|
52
|
+
supabaseAdmin: SupabaseClient;
|
|
53
|
+
/** JWT-derived identity. For the full Supabase User object, call `supabase.auth.getUser()`. */
|
|
54
|
+
userClaims: UserClaims | null;
|
|
55
|
+
claims: JWTClaims | null;
|
|
56
|
+
authType: Allow;
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { JWTClaims as a, UserClaims as c, Credentials as i, WithSupabaseConfig as l, AllowWithKey as n, SupabaseContext as o, AuthResult as r, SupabaseEnv as s, Allow as t };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
type Allow = 'always' | 'public' | 'secret' | 'user';
|
|
5
|
+
type AllowWithKey = Allow | `public:${string}` | `secret:${string}`;
|
|
6
|
+
interface SupabaseEnv {
|
|
7
|
+
url: string;
|
|
8
|
+
publishableKeys: Record<string, string>;
|
|
9
|
+
secretKeys: Record<string, string>;
|
|
10
|
+
jwks: JsonWebKeySet | null;
|
|
11
|
+
}
|
|
12
|
+
interface JsonWebKeySet {
|
|
13
|
+
keys: JsonWebKey[];
|
|
14
|
+
}
|
|
15
|
+
interface Credentials {
|
|
16
|
+
token: string | null;
|
|
17
|
+
apikey: string | null;
|
|
18
|
+
}
|
|
19
|
+
interface AuthResult {
|
|
20
|
+
authType: Allow;
|
|
21
|
+
token: string | null;
|
|
22
|
+
userClaims: UserClaims | null;
|
|
23
|
+
claims: JWTClaims | null;
|
|
24
|
+
keyName?: string | null;
|
|
25
|
+
}
|
|
26
|
+
interface JWTClaims {
|
|
27
|
+
sub: string;
|
|
28
|
+
iss?: string;
|
|
29
|
+
aud?: string | string[];
|
|
30
|
+
exp?: number;
|
|
31
|
+
iat?: number;
|
|
32
|
+
role?: string;
|
|
33
|
+
email?: string;
|
|
34
|
+
app_metadata?: Record<string, unknown>;
|
|
35
|
+
user_metadata?: Record<string, unknown>;
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
interface UserClaims {
|
|
39
|
+
id: string;
|
|
40
|
+
role?: string;
|
|
41
|
+
email?: string;
|
|
42
|
+
appMetadata?: Record<string, unknown>;
|
|
43
|
+
userMetadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
interface WithSupabaseConfig {
|
|
46
|
+
allow?: AllowWithKey | AllowWithKey[];
|
|
47
|
+
env?: Partial<SupabaseEnv>;
|
|
48
|
+
cors?: boolean | Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
interface SupabaseContext {
|
|
51
|
+
supabase: SupabaseClient;
|
|
52
|
+
supabaseAdmin: SupabaseClient;
|
|
53
|
+
/** JWT-derived identity. For the full Supabase User object, call `supabase.auth.getUser()`. */
|
|
54
|
+
userClaims: UserClaims | null;
|
|
55
|
+
claims: JWTClaims | null;
|
|
56
|
+
authType: Allow;
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { JWTClaims as a, UserClaims as c, Credentials as i, WithSupabaseConfig as l, AllowWithKey as n, SupabaseContext as o, AuthResult as r, SupabaseEnv as s, Allow as t };
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
let _supabase_supabase_js = require("@supabase/supabase-js");
|
|
2
|
+
let jose = require("jose");
|
|
3
|
+
|
|
4
|
+
//#region src/errors.ts
|
|
5
|
+
var EnvError = class extends Error {
|
|
6
|
+
constructor(message, code = "ENV_ERROR") {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = 500;
|
|
9
|
+
this.name = "EnvError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var AuthError = class extends Error {
|
|
14
|
+
constructor(message, code = "AUTH_ERROR", status = 401) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "AuthError";
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.status = status;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/core/resolve-env.ts
|
|
24
|
+
function getEnvVar(name) {
|
|
25
|
+
if (typeof Deno !== "undefined" && Deno.env?.get) return Deno.env.get(name);
|
|
26
|
+
if (typeof process !== "undefined" && process.env) return process.env[name];
|
|
27
|
+
}
|
|
28
|
+
function parseKeys(raw) {
|
|
29
|
+
if (!raw) return {};
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(raw);
|
|
32
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
|
|
33
|
+
return parsed;
|
|
34
|
+
} catch {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function resolveKeys(singularVar, pluralVar) {
|
|
39
|
+
const plural = getEnvVar(pluralVar);
|
|
40
|
+
if (plural) return parseKeys(plural);
|
|
41
|
+
const singular = getEnvVar(singularVar);
|
|
42
|
+
if (singular) return { default: singular };
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
function parseJwks(raw) {
|
|
46
|
+
if (!raw) return null;
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
if (Array.isArray(parsed)) return { keys: parsed };
|
|
50
|
+
if (parsed?.keys && Array.isArray(parsed.keys)) return parsed;
|
|
51
|
+
return null;
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function resolveEnv(overrides) {
|
|
57
|
+
const url = overrides?.url ?? getEnvVar("SUPABASE_URL");
|
|
58
|
+
if (!url) return {
|
|
59
|
+
data: null,
|
|
60
|
+
error: new EnvError("SUPABASE_URL is required but not set", "MISSING_SUPABASE_URL")
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
data: {
|
|
64
|
+
url,
|
|
65
|
+
publishableKeys: overrides?.publishableKeys ?? resolveKeys("SUPABASE_PUBLISHABLE_KEY", "SUPABASE_PUBLISHABLE_KEYS"),
|
|
66
|
+
secretKeys: overrides?.secretKeys ?? resolveKeys("SUPABASE_SECRET_KEY", "SUPABASE_SECRET_KEYS"),
|
|
67
|
+
jwks: overrides?.jwks ?? parseJwks(getEnvVar("SUPABASE_JWKS"))
|
|
68
|
+
},
|
|
69
|
+
error: null
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/core/create-admin-client.ts
|
|
75
|
+
function createAdminClient(env, keyName) {
|
|
76
|
+
const { data: resolved, error } = resolveEnv(env);
|
|
77
|
+
if (error) throw error;
|
|
78
|
+
const name = keyName ?? "default";
|
|
79
|
+
const keys = resolved.secretKeys;
|
|
80
|
+
const secretKey = keys[name] ?? (keyName == null ? Object.values(keys)[0] : void 0);
|
|
81
|
+
if (!secretKey) throw new EnvError(name === "default" ? "No default secret key found. Set SUPABASE_SECRET_KEY or include a \"default\" entry in SUPABASE_SECRET_KEYS." : `No "${name}" secret key found. Include a "${name}" entry in SUPABASE_SECRET_KEYS.`, "MISSING_SECRET_KEY");
|
|
82
|
+
return (0, _supabase_supabase_js.createClient)(resolved.url, secretKey, { auth: {
|
|
83
|
+
persistSession: false,
|
|
84
|
+
autoRefreshToken: false,
|
|
85
|
+
detectSessionInUrl: false
|
|
86
|
+
} });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/core/create-context-client.ts
|
|
91
|
+
function createContextClient(token, env, keyName) {
|
|
92
|
+
const { data: resolved, error } = resolveEnv(env);
|
|
93
|
+
if (error) throw error;
|
|
94
|
+
const name = keyName ?? "default";
|
|
95
|
+
const keys = resolved.publishableKeys;
|
|
96
|
+
const anonKey = keys[name] ?? (keyName == null ? Object.values(keys)[0] : void 0);
|
|
97
|
+
if (!anonKey) throw new EnvError(name === "default" ? "No default publishable key found. Set SUPABASE_PUBLISHABLE_KEY or include a \"default\" entry in SUPABASE_PUBLISHABLE_KEYS." : `No "${name}" publishable key found. Include a "${name}" entry in SUPABASE_PUBLISHABLE_KEYS.`, "MISSING_PUBLISHABLE_KEY");
|
|
98
|
+
return (0, _supabase_supabase_js.createClient)(resolved.url, anonKey, {
|
|
99
|
+
global: { headers: token ? { Authorization: `Bearer ${token}` } : {} },
|
|
100
|
+
auth: {
|
|
101
|
+
persistSession: false,
|
|
102
|
+
autoRefreshToken: false,
|
|
103
|
+
detectSessionInUrl: false
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/core/extract-credentials.ts
|
|
110
|
+
function extractCredentials(request) {
|
|
111
|
+
const authHeader = request.headers.get("authorization");
|
|
112
|
+
return {
|
|
113
|
+
token: authHeader?.startsWith("Bearer ") ? authHeader.slice(7) || null : null,
|
|
114
|
+
apikey: request.headers.get("apikey")
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/core/utils/timing-safe-equal.ts
|
|
120
|
+
const encoder = new TextEncoder();
|
|
121
|
+
async function timingSafeEqual(a, b) {
|
|
122
|
+
const key = crypto.getRandomValues(new Uint8Array(32));
|
|
123
|
+
const cryptoKey = await crypto.subtle.importKey("raw", key, {
|
|
124
|
+
name: "HMAC",
|
|
125
|
+
hash: "SHA-256"
|
|
126
|
+
}, false, ["sign"]);
|
|
127
|
+
const [sigA, sigB] = await Promise.all([crypto.subtle.sign("HMAC", cryptoKey, encoder.encode(a)), crypto.subtle.sign("HMAC", cryptoKey, encoder.encode(b))]);
|
|
128
|
+
if (sigA.byteLength !== sigB.byteLength) return false;
|
|
129
|
+
const viewA = new Uint8Array(sigA);
|
|
130
|
+
const viewB = new Uint8Array(sigB);
|
|
131
|
+
let result = 0;
|
|
132
|
+
for (let i = 0; i < viewA.length; i++) result |= viewA[i] ^ viewB[i];
|
|
133
|
+
return result === 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/core/verify-credentials.ts
|
|
138
|
+
function parseAllowMode(mode) {
|
|
139
|
+
if (mode === "always" || mode === "public" || mode === "secret" || mode === "user") return {
|
|
140
|
+
base: mode,
|
|
141
|
+
keyName: null
|
|
142
|
+
};
|
|
143
|
+
const colonIndex = mode.indexOf(":");
|
|
144
|
+
const base = mode.slice(0, colonIndex);
|
|
145
|
+
const keyName = mode.slice(colonIndex + 1);
|
|
146
|
+
if (!keyName) return {
|
|
147
|
+
base,
|
|
148
|
+
keyName: null
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
base,
|
|
152
|
+
keyName
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function claimsToUserClaims(claims) {
|
|
156
|
+
return {
|
|
157
|
+
id: claims.sub,
|
|
158
|
+
role: claims.role,
|
|
159
|
+
email: claims.email,
|
|
160
|
+
appMetadata: claims.app_metadata,
|
|
161
|
+
userMetadata: claims.user_metadata
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
async function tryMode(mode, credentials, env) {
|
|
165
|
+
const { base, keyName } = parseAllowMode(mode);
|
|
166
|
+
switch (base) {
|
|
167
|
+
case "always": return {
|
|
168
|
+
authType: "always",
|
|
169
|
+
token: null,
|
|
170
|
+
userClaims: null,
|
|
171
|
+
claims: null,
|
|
172
|
+
keyName: null
|
|
173
|
+
};
|
|
174
|
+
case "public": {
|
|
175
|
+
if (!credentials.apikey) return null;
|
|
176
|
+
const keys = env.publishableKeys;
|
|
177
|
+
if (keyName === "*") {
|
|
178
|
+
for (const [name, value] of Object.entries(keys)) if (await timingSafeEqual(credentials.apikey, value)) return {
|
|
179
|
+
authType: "public",
|
|
180
|
+
token: null,
|
|
181
|
+
userClaims: null,
|
|
182
|
+
claims: null,
|
|
183
|
+
keyName: name
|
|
184
|
+
};
|
|
185
|
+
} else {
|
|
186
|
+
const name = keyName ?? "default";
|
|
187
|
+
const value = keys[name];
|
|
188
|
+
if (value && await timingSafeEqual(credentials.apikey, value)) return {
|
|
189
|
+
authType: "public",
|
|
190
|
+
token: null,
|
|
191
|
+
userClaims: null,
|
|
192
|
+
claims: null,
|
|
193
|
+
keyName: name
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
case "secret": {
|
|
199
|
+
if (!credentials.apikey) return null;
|
|
200
|
+
const keys = env.secretKeys;
|
|
201
|
+
if (keyName === "*") {
|
|
202
|
+
for (const [name, value] of Object.entries(keys)) if (await timingSafeEqual(credentials.apikey, value)) return {
|
|
203
|
+
authType: "secret",
|
|
204
|
+
token: null,
|
|
205
|
+
userClaims: null,
|
|
206
|
+
claims: null,
|
|
207
|
+
keyName: name
|
|
208
|
+
};
|
|
209
|
+
} else {
|
|
210
|
+
const name = keyName ?? "default";
|
|
211
|
+
const value = keys[name];
|
|
212
|
+
if (value && await timingSafeEqual(credentials.apikey, value)) return {
|
|
213
|
+
authType: "secret",
|
|
214
|
+
token: null,
|
|
215
|
+
userClaims: null,
|
|
216
|
+
claims: null,
|
|
217
|
+
keyName: name
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
case "user":
|
|
223
|
+
if (!credentials.token) return null;
|
|
224
|
+
if (!env.jwks) return null;
|
|
225
|
+
try {
|
|
226
|
+
const jwkSet = (0, jose.createLocalJWKSet)(env.jwks);
|
|
227
|
+
const { payload } = await (0, jose.jwtVerify)(credentials.token, jwkSet);
|
|
228
|
+
if (typeof payload.sub !== "string") return null;
|
|
229
|
+
const claims = payload;
|
|
230
|
+
return {
|
|
231
|
+
authType: "user",
|
|
232
|
+
token: credentials.token,
|
|
233
|
+
userClaims: claimsToUserClaims(claims),
|
|
234
|
+
claims,
|
|
235
|
+
keyName: null
|
|
236
|
+
};
|
|
237
|
+
} catch {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
default: return null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function verifyCredentials(credentials, options) {
|
|
244
|
+
const { data: env, error: envError } = resolveEnv(options.env);
|
|
245
|
+
if (envError) return {
|
|
246
|
+
data: null,
|
|
247
|
+
error: new AuthError(envError.message, envError.code, 500)
|
|
248
|
+
};
|
|
249
|
+
const modes = Array.isArray(options.allow) ? options.allow : [options.allow];
|
|
250
|
+
for (const mode of modes) {
|
|
251
|
+
const result = await tryMode(mode, credentials, env);
|
|
252
|
+
if (result) return {
|
|
253
|
+
data: result,
|
|
254
|
+
error: null
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
data: null,
|
|
259
|
+
error: new AuthError("Invalid credentials", "INVALID_CREDENTIALS", 401)
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
//#endregion
|
|
264
|
+
//#region src/core/verify-auth.ts
|
|
265
|
+
async function verifyAuth(request, options) {
|
|
266
|
+
return verifyCredentials(extractCredentials(request), options);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
Object.defineProperty(exports, 'AuthError', {
|
|
271
|
+
enumerable: true,
|
|
272
|
+
get: function () {
|
|
273
|
+
return AuthError;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
Object.defineProperty(exports, 'EnvError', {
|
|
277
|
+
enumerable: true,
|
|
278
|
+
get: function () {
|
|
279
|
+
return EnvError;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
Object.defineProperty(exports, 'createAdminClient', {
|
|
283
|
+
enumerable: true,
|
|
284
|
+
get: function () {
|
|
285
|
+
return createAdminClient;
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
Object.defineProperty(exports, 'createContextClient', {
|
|
289
|
+
enumerable: true,
|
|
290
|
+
get: function () {
|
|
291
|
+
return createContextClient;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
Object.defineProperty(exports, 'extractCredentials', {
|
|
295
|
+
enumerable: true,
|
|
296
|
+
get: function () {
|
|
297
|
+
return extractCredentials;
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
Object.defineProperty(exports, 'resolveEnv', {
|
|
301
|
+
enumerable: true,
|
|
302
|
+
get: function () {
|
|
303
|
+
return resolveEnv;
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
Object.defineProperty(exports, 'verifyAuth', {
|
|
307
|
+
enumerable: true,
|
|
308
|
+
get: function () {
|
|
309
|
+
return verifyAuth;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
Object.defineProperty(exports, 'verifyCredentials', {
|
|
313
|
+
enumerable: true,
|
|
314
|
+
get: function () {
|
|
315
|
+
return verifyCredentials;
|
|
316
|
+
}
|
|
317
|
+
});
|