mates-auth 1.0.0-beta.1

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.
@@ -0,0 +1,3 @@
1
+ export { useJWT, auth, type AuthDuration, type AuthClaims, type AuthContext, type JWTOptions, type AuthLoginOptions, } from "./use-jwt.js";
2
+ export { useArctic, arcticProvider, listArcticProviders, type ArcticBuiltInProvider, type ArcticTokenSet, type ArcticProfile, type ArcticProviderConfig, type ArcticProvidersConfig, type ArcticSuccessHandler, type ArcticUseOptions, type ArcticProviderHandler, type ArcticCustomProvider, type ArcticProfileLoader, } from "./use-arctic.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,IAAI,EACJ,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { useJWT, auth, } from "./use-jwt.js";
2
+ export { useArctic, arcticProvider, listArcticProviders, } from "./use-arctic.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,IAAI,GAML,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,SAAS,EACT,cAAc,EACd,mBAAmB,GAWpB,MAAM,iBAAiB,CAAC"}
package/dist/sso.d.ts ADDED
@@ -0,0 +1,90 @@
1
+ /**
2
+ * mates-fullstack-auth — sso.ts
3
+ *
4
+ * Optional cross-domain SSO middleware.
5
+ *
6
+ * Setup:
7
+ * Auth server (auth.com): useSsoProvider({ secret, login: "/login" })
8
+ * App server (app1.com): useSsoClient({ authUrl, secret, protected: ["/dashboard"] })
9
+ *
10
+ * Flow:
11
+ * app1.com/dashboard → auth.com/api/sso/code?redirect=... → login (if needed)
12
+ * → code JWT → app1.com/auth/sso/callback → auth.login()
13
+ */
14
+ export interface SsoProviderOptions {
15
+ /**
16
+ * Shared secret between auth server and app servers.
17
+ * Used to sign and verify the short-lived code JWTs.
18
+ */
19
+ secret: string;
20
+ /**
21
+ * Path to the login page on the auth server.
22
+ * Unauthenticated users are redirected here with a `?next` param
23
+ * so they return to `/api/sso/code` after login.
24
+ * @default "/login"
25
+ */
26
+ login?: string;
27
+ /**
28
+ * Lifetime of the code JWT in seconds.
29
+ * @default 30
30
+ */
31
+ codeLifetime?: number;
32
+ /**
33
+ * Allowed redirect origins for the `redirect` parameter.
34
+ * Only URLs starting with these prefixes are accepted.
35
+ * Must include the protocol (e.g. "https://app1.com").
36
+ * When unset, only relative paths (starting with `/`) are allowed.
37
+ */
38
+ allowedOrigins?: string[];
39
+ }
40
+ export interface SsoClientOptions {
41
+ /**
42
+ * Base URL of the auth server (e.g. "https://auth.com").
43
+ */
44
+ authUrl: string;
45
+ /**
46
+ * Shared secret — must match exactly what the auth server uses.
47
+ */
48
+ secret: string;
49
+ /**
50
+ * Paths that require authentication.
51
+ * Unauthenticated visitors are redirected to the auth server.
52
+ * @default []
53
+ */
54
+ protected?: string[];
55
+ /**
56
+ * Where to redirect after a successful SSO login.
57
+ * @default "/"
58
+ */
59
+ afterLogin?: string;
60
+ }
61
+ /**
62
+ * Register SSO provider endpoints on the auth server.
63
+ *
64
+ * Creates:
65
+ * GET /api/sso/code — generates a code JWT if authenticated
66
+ * GET /api/sso/after-login — where the login page redirects after auth
67
+ *
68
+ * @example
69
+ * useSsoProvider({
70
+ * secret: process.env.SSO_SECRET!,
71
+ * login: "/login",
72
+ * });
73
+ */
74
+ export declare function useSsoProvider(options: SsoProviderOptions): void;
75
+ /**
76
+ * Register SSO client endpoints and guarded routes on an app server.
77
+ *
78
+ * Creates:
79
+ * GET /auth/sso/callback — verifies the code JWT, calls auth.login()
80
+ * onRequest guard — redirects protected routes to the auth server
81
+ *
82
+ * @example
83
+ * useSsoClient({
84
+ * authUrl: "https://auth.com",
85
+ * secret: process.env.SSO_SECRET!,
86
+ * protected: ["/dashboard", "/settings"],
87
+ * });
88
+ */
89
+ export declare function useSsoClient(options: SsoClientOptions): void;
90
+ //# sourceMappingURL=sso.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../src/sso.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA4CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CA0HhE;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAoH5D"}
package/dist/sso.js ADDED
@@ -0,0 +1,303 @@
1
+ /**
2
+ * mates-fullstack-auth — sso.ts
3
+ *
4
+ * Optional cross-domain SSO middleware.
5
+ *
6
+ * Setup:
7
+ * Auth server (auth.com): useSsoProvider({ secret, login: "/login" })
8
+ * App server (app1.com): useSsoClient({ authUrl, secret, protected: ["/dashboard"] })
9
+ *
10
+ * Flow:
11
+ * app1.com/dashboard → auth.com/api/sso/code?redirect=... → login (if needed)
12
+ * → code JWT → app1.com/auth/sso/callback → auth.login()
13
+ */
14
+ import crypto from "node:crypto";
15
+ import { onRequest, jwt } from "mates-fullstack";
16
+ import { auth } from "./use-jwt.js";
17
+ // ─── Cookie helpers (internal, temporary) ─────────────────────────────────────
18
+ const SSO_REDIRECT_COOKIE = "sso_redirect";
19
+ const SSO_AFTER_LOGIN_COOKIE = "sso_after_login";
20
+ const SSO_CODE_PARAM = "code";
21
+ function _setTempCookie(ctx, name, value, path) {
22
+ ctx.cookie.set(name, value, {
23
+ httpOnly: true,
24
+ sameSite: "lax",
25
+ path,
26
+ maxAge: 300, // 5 min
27
+ secure: process.env.NODE_ENV === "production",
28
+ });
29
+ }
30
+ function _clearTempCookie(ctx, name, path) {
31
+ ctx.cookie.delete(name, { path });
32
+ }
33
+ /**
34
+ * Resolve the public origin for the current request.
35
+ * Used by the client to build the callback URL for the auth server.
36
+ */
37
+ function _publicOrigin(req) {
38
+ const url = new URL(req.url);
39
+ const host = req.headers.get("x-forwarded-host") ?? url.host;
40
+ const proto = req.headers.get("x-forwarded-proto") ?? url.protocol.slice(0, -1);
41
+ return `${proto}://${host}`;
42
+ }
43
+ // ─── Provider side (auth.com) ────────────────────────────────────────────────
44
+ const SSO_CODE_PATH = "/api/sso/code";
45
+ const SSO_AFTER_LOGIN_PATH = "/api/sso/after-login";
46
+ /**
47
+ * Register SSO provider endpoints on the auth server.
48
+ *
49
+ * Creates:
50
+ * GET /api/sso/code — generates a code JWT if authenticated
51
+ * GET /api/sso/after-login — where the login page redirects after auth
52
+ *
53
+ * @example
54
+ * useSsoProvider({
55
+ * secret: process.env.SSO_SECRET!,
56
+ * login: "/login",
57
+ * });
58
+ */
59
+ export function useSsoProvider(options) {
60
+ const secret = options.secret;
61
+ if (!secret || secret.length < 8) {
62
+ throw new Error("useSsoProvider: secret must be at least 8 characters.");
63
+ }
64
+ const login = options.login ?? "/login";
65
+ const codeLifetime = options.codeLifetime ?? 30;
66
+ const tokens = jwt(secret);
67
+ onRequest(async (c) => {
68
+ const url = new URL(c.req.raw.url);
69
+ const pathname = url.pathname;
70
+ // ── Entry: GET /api/sso/code?redirect=... ──────────────────────────────
71
+ if (pathname === SSO_CODE_PATH) {
72
+ if (c.req.method !== "GET") {
73
+ return new Response(JSON.stringify({ error: "Method not allowed" }), {
74
+ status: 405,
75
+ headers: { "content-type": "application/json" },
76
+ });
77
+ }
78
+ const redirect = url.searchParams.get("redirect");
79
+ if (!redirect) {
80
+ return new Response(JSON.stringify({ error: 'Missing "redirect" parameter' }), { status: 400, headers: { "content-type": "application/json" } });
81
+ }
82
+ if (!_isValidRedirect(redirect, options.allowedOrigins)) {
83
+ return new Response(JSON.stringify({ error: "Invalid redirect target" }), { status: 400, headers: { "content-type": "application/json" } });
84
+ }
85
+ // Store the redirect target in a cookie so it survives login redirect
86
+ _setTempCookie(c, SSO_REDIRECT_COOKIE, redirect, SSO_CODE_PATH);
87
+ _setTempCookie(c, SSO_AFTER_LOGIN_COOKIE, redirect, SSO_AFTER_LOGIN_PATH);
88
+ const userId = (c.auth?.sub ?? c.auth?.userId);
89
+ if (!userId) {
90
+ // Not authenticated — redirect to login page
91
+ const next = encodeURIComponent(SSO_CODE_PATH);
92
+ const loginUrl = `${login}?next=${next}`;
93
+ return new Response(null, {
94
+ status: 302,
95
+ headers: { location: loginUrl },
96
+ });
97
+ }
98
+ // Authenticated — generate a short-lived code JWT and redirect
99
+ let aud;
100
+ try {
101
+ aud = new URL(redirect).origin;
102
+ }
103
+ catch { }
104
+ const code = await tokens.sign({
105
+ sub: userId,
106
+ ..._pickClaims(c.auth ?? {}),
107
+ jti: crypto.randomUUID(),
108
+ ...(aud ? { aud } : {}),
109
+ }, { expiresIn: codeLifetime });
110
+ _clearTempCookie(c, SSO_REDIRECT_COOKIE, SSO_CODE_PATH);
111
+ _clearTempCookie(c, SSO_AFTER_LOGIN_COOKIE, SSO_AFTER_LOGIN_PATH);
112
+ const stateParam = url.searchParams.get("state") || "";
113
+ const separator = redirect.includes("?") ? "&" : "?";
114
+ const location = `${redirect}${separator}${SSO_CODE_PARAM}=${code}${stateParam ? `&state=${encodeURIComponent(stateParam)}` : ""}`;
115
+ return new Response(null, { status: 302, headers: { location } });
116
+ }
117
+ // ── After login: GET /api/sso/after-login ──────────────────────────────
118
+ if (pathname === SSO_AFTER_LOGIN_PATH) {
119
+ if (c.req.method !== "GET") {
120
+ return new Response(JSON.stringify({ error: "Method not allowed" }), {
121
+ status: 405,
122
+ headers: { "content-type": "application/json" },
123
+ });
124
+ }
125
+ const redirect = c.cookie.get(SSO_AFTER_LOGIN_COOKIE) ??
126
+ c.cookie.get(SSO_REDIRECT_COOKIE);
127
+ _clearTempCookie(c, SSO_AFTER_LOGIN_COOKIE, SSO_AFTER_LOGIN_PATH);
128
+ const userId = (c.auth?.sub ?? c.auth?.userId);
129
+ if (!userId) {
130
+ const loginUrl = `${login}?next=${encodeURIComponent(SSO_AFTER_LOGIN_PATH)}`;
131
+ return new Response(null, {
132
+ status: 302,
133
+ headers: { location: loginUrl },
134
+ });
135
+ }
136
+ if (redirect) {
137
+ let aud;
138
+ try {
139
+ aud = new URL(redirect).origin;
140
+ }
141
+ catch { }
142
+ const code = await tokens.sign({
143
+ sub: userId,
144
+ ..._pickClaims(c.auth ?? {}),
145
+ jti: crypto.randomUUID(),
146
+ ...(aud ? { aud } : {}),
147
+ }, { expiresIn: codeLifetime });
148
+ const location = `${redirect}${redirect.includes("?") ? "&" : "?"}${SSO_CODE_PARAM}=${code}`;
149
+ return new Response(null, { status: 302, headers: { location } });
150
+ }
151
+ // No redirect stored — go to home
152
+ return new Response(null, { status: 302, headers: { location: "/" } });
153
+ }
154
+ });
155
+ }
156
+ // ─── Client side (app1.com, app2.com) ─────────────────────────────────────────
157
+ const SSO_CALLBACK_PATH = "/auth/sso/callback";
158
+ /**
159
+ * Register SSO client endpoints and guarded routes on an app server.
160
+ *
161
+ * Creates:
162
+ * GET /auth/sso/callback — verifies the code JWT, calls auth.login()
163
+ * onRequest guard — redirects protected routes to the auth server
164
+ *
165
+ * @example
166
+ * useSsoClient({
167
+ * authUrl: "https://auth.com",
168
+ * secret: process.env.SSO_SECRET!,
169
+ * protected: ["/dashboard", "/settings"],
170
+ * });
171
+ */
172
+ export function useSsoClient(options) {
173
+ const { authUrl, secret, afterLogin } = options;
174
+ const protectedPaths = options.protected ?? [];
175
+ if (!secret || secret.length < 8) {
176
+ throw new Error("useSsoClient: secret must be at least 8 characters.");
177
+ }
178
+ if (!authUrl) {
179
+ throw new Error("useSsoClient: authUrl is required.");
180
+ }
181
+ const tokens = jwt(secret);
182
+ const _consumedJtis = new Set();
183
+ // ── Callback: GET /auth/sso/callback?code=... ────────────────────────────
184
+ onRequest(async (c) => {
185
+ const url = new URL(c.req.raw.url);
186
+ if (url.pathname !== SSO_CALLBACK_PATH)
187
+ return;
188
+ const code = url.searchParams.get(SSO_CODE_PARAM);
189
+ const next = url.searchParams.get("next");
190
+ if (!code) {
191
+ return new Response(JSON.stringify({ error: `Missing "${SSO_CODE_PARAM}" parameter` }), { status: 400, headers: { "content-type": "application/json" } });
192
+ }
193
+ // Verify the code JWT — ensures it was signed by the auth server
194
+ const payload = await tokens.verify(code);
195
+ if (!payload) {
196
+ return new Response(JSON.stringify({ error: "Invalid or expired code" }), { status: 401, headers: { "content-type": "application/json" } });
197
+ }
198
+ // Replay protection — reject reused JTIs
199
+ if (payload.jti && typeof payload.jti === "string") {
200
+ if (_consumedJtis.has(payload.jti)) {
201
+ return new Response(JSON.stringify({ error: "Code already used" }), {
202
+ status: 401,
203
+ headers: { "content-type": "application/json" },
204
+ });
205
+ }
206
+ _consumedJtis.add(payload.jti);
207
+ if (_consumedJtis.size > 10_000)
208
+ _consumedJtis.clear();
209
+ }
210
+ // Verify audience matches this app
211
+ const appOrigin = _publicOrigin(c.req.raw);
212
+ if (payload.aud && payload.aud !== appOrigin) {
213
+ return new Response(JSON.stringify({ error: "Code audience mismatch" }), {
214
+ status: 401,
215
+ headers: { "content-type": "application/json" },
216
+ });
217
+ }
218
+ // Verify state parameter
219
+ const stateParam = url.searchParams.get("state");
220
+ const storedState = c.cookie.get("sso_state");
221
+ if (stateParam && storedState && stateParam !== storedState) {
222
+ return new Response(JSON.stringify({ error: "Invalid state" }), {
223
+ status: 401,
224
+ headers: { "content-type": "application/json" },
225
+ });
226
+ }
227
+ // Clear the state cookie
228
+ c.cookie.delete("sso_state", { path: "/" });
229
+ // Extract claims — strip JWT timing fields
230
+ const { iat: _iat, exp: _exp, nbf: _nbf, jti: _jti, ...claims } = payload;
231
+ await auth.login(c, claims);
232
+ const location = next ?? afterLogin ?? "/";
233
+ return new Response(null, { status: 302, headers: { location } });
234
+ });
235
+ // ── Guard protected routes ──────────────────────────────────────────────
236
+ if (protectedPaths.length > 0) {
237
+ onRequest((c) => {
238
+ const url = new URL(c.req.raw.url);
239
+ const pathname = url.pathname;
240
+ const isProtected = protectedPaths.some((p) => pathname === p || pathname.startsWith(p + "/"));
241
+ if (!isProtected)
242
+ return;
243
+ // Already authenticated
244
+ const userId = c.auth?.sub ?? c.auth?.userId;
245
+ if (userId)
246
+ return;
247
+ // Redirect to auth server
248
+ const origin = _publicOrigin(c.req.raw);
249
+ const callbackUrl = `${origin}${SSO_CALLBACK_PATH}`;
250
+ const codeUrl = `${authUrl}${SSO_CODE_PATH}`;
251
+ const state = crypto.randomUUID();
252
+ c.cookie.set("sso_state", state, {
253
+ httpOnly: true,
254
+ sameSite: "lax",
255
+ path: "/",
256
+ maxAge: 300,
257
+ secure: process.env.NODE_ENV === "production",
258
+ });
259
+ const redirectTarget = `${codeUrl}?redirect=${encodeURIComponent(callbackUrl + "?next=" + encodeURIComponent(pathname))}&state=${encodeURIComponent(state)}`;
260
+ return new Response(null, {
261
+ status: 302,
262
+ headers: { location: redirectTarget },
263
+ });
264
+ });
265
+ }
266
+ }
267
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
268
+ /**
269
+ * Validate the redirect URL to prevent open redirect attacks.
270
+ * - Relative paths (starting with `/`) are always allowed.
271
+ * - Absolute URLs with a host are only allowed if their origin matches
272
+ * one of the allowedOrigins.
273
+ */
274
+ function _isValidRedirect(redirect, allowedOrigins) {
275
+ // Relative paths are safe — always allow
276
+ if (redirect.startsWith("/"))
277
+ return true;
278
+ // Absolute URL — must match an allowed origin
279
+ if (!allowedOrigins || allowedOrigins.length === 0)
280
+ return false;
281
+ try {
282
+ const u = new URL(redirect);
283
+ const origin = `${u.protocol}//${u.host}`;
284
+ return allowedOrigins.some((allowed) => allowed === origin || redirect.startsWith(allowed));
285
+ }
286
+ catch {
287
+ return false;
288
+ }
289
+ }
290
+ /**
291
+ * Pick safe display claims from ctx.auth to include in the code JWT.
292
+ */
293
+ function _pickClaims(auth) {
294
+ const safe = {};
295
+ const keys = ["userId", "userName", "username", "name", "email", "roles"];
296
+ for (const key of keys) {
297
+ const val = auth[key];
298
+ if (val !== undefined)
299
+ safe[key] = val;
300
+ }
301
+ return safe;
302
+ }
303
+ //# sourceMappingURL=sso.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.js","sourceRoot":"","sources":["../src/sso.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { type OAuth2Tokens } from "arctic";
2
+ import { type Context, type CookieOptions } from "mates-fullstack";
3
+ export type ArcticBuiltInProvider = "apple" | "discord" | "facebook" | "github" | "gitlab" | "google" | "linkedin" | "microsoft" | "spotify" | "twitter";
4
+ export interface ArcticTokenSet {
5
+ accessToken: string | null;
6
+ refreshToken: string | null;
7
+ idToken: string | null;
8
+ tokenType: string | null;
9
+ expiresAt: Date | null;
10
+ scopes: string[] | null;
11
+ raw: object;
12
+ }
13
+ export interface ArcticProfile<Raw = unknown> {
14
+ provider: string;
15
+ id: string;
16
+ email: string | null;
17
+ name: string | null;
18
+ avatar: string | null;
19
+ username?: string | null;
20
+ raw: Raw;
21
+ tokens: ArcticTokenSet;
22
+ }
23
+ export interface ArcticProviderConfig {
24
+ clientId: string;
25
+ clientSecret?: string | null;
26
+ redirectUri?: string;
27
+ scopes?: string[];
28
+ /** Microsoft Entra ID tenant. Defaults to "common". */
29
+ tenant?: string;
30
+ /** Apple Team ID. */
31
+ teamId?: string;
32
+ /** Apple Key ID. */
33
+ keyId?: string;
34
+ /** Apple private key in PKCS#8 PEM format. */
35
+ privateKey?: string;
36
+ /** GitLab base URL. Defaults to https://gitlab.com. */
37
+ baseURL?: string;
38
+ /** Override the built-in profile fetcher or add one for custom providers. */
39
+ profile?: ArcticProfileLoader;
40
+ /** Override whether this provider uses PKCE. */
41
+ usesPKCE?: boolean;
42
+ /**
43
+ * Called after the provider returns a profile.
44
+ * Return the claims to bake into the JWT — typically after an upsert in your DB.
45
+ */
46
+ onSuccess: ArcticSuccessHandler;
47
+ }
48
+ export type ArcticProvidersConfig = Partial<Record<ArcticBuiltInProvider | string, ArcticProviderConfig | ArcticCustomProvider>>;
49
+ /**
50
+ * Called after the provider returns a verified profile.
51
+ * You are fully in control — call `auth.login(ctx, claims)` to issue tokens,
52
+ * update the DB to link an account, or do nothing at all.
53
+ * Return a path string to override the post-OAuth redirect.
54
+ */
55
+ export type ArcticSuccessHandler = (profile: ArcticProfile, ctx: Context) => string | void | Promise<string | void>;
56
+ export interface ArcticUseOptions {
57
+ /** Route base for OAuth endpoints. Default: "/auth". */
58
+ basePath?: string;
59
+ /** Default redirect after login. Default: "/". */
60
+ afterLogin?: string;
61
+ /** Redirect after OAuth failure. If omitted, failures return JSON. */
62
+ onErrorRedirect?: string;
63
+ /** Cookie path/domain/sameSite/secure controls for temporary OAuth cookies. */
64
+ cookie?: Pick<CookieOptions, "path" | "domain" | "sameSite" | "secure">;
65
+ /** Temporary OAuth state cookie lifetime in seconds. Default: 10 minutes. */
66
+ stateMaxAge?: number;
67
+ }
68
+ export interface ArcticProviderHandler {
69
+ defaultScopes: string[];
70
+ usesPKCE: boolean;
71
+ start(config: ArcticProviderConfig, redirectUri: string, state: string, codeVerifier: string | null): Promise<URL> | URL;
72
+ callback(config: ArcticProviderConfig, redirectUri: string, code: string, codeVerifier: string | null, providerName: string): Promise<ArcticProfile>;
73
+ }
74
+ export interface ArcticCustomProvider extends ArcticProviderConfig {
75
+ handler: ArcticProviderHandler;
76
+ }
77
+ export type ArcticProfileLoader = (tokens: OAuth2Tokens, providerName: string) => Promise<Omit<ArcticProfile, "provider" | "tokens">>;
78
+ /**
79
+ * Register social login routes for every configured provider.
80
+ *
81
+ * The framework automatically handles:
82
+ * GET /auth/:provider — redirect to provider
83
+ * GET /auth/:provider/callback — exchange code, call onSuccess, set cookies
84
+ *
85
+ * @example
86
+ * useArctic({
87
+ * google: {
88
+ * clientId: process.env.GOOGLE_CLIENT_ID!,
89
+ * clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
90
+ * onSuccess: async (profile) => {
91
+ * const user = await db.upsert({ provider: profile.provider, providerId: profile.id, ... });
92
+ * return { userId: user.id, email: user.email, roles: user.roles };
93
+ * },
94
+ * },
95
+ * });
96
+ */
97
+ export declare function useArctic(providers: ArcticProvidersConfig, options?: ArcticUseOptions): void;
98
+ /** Define a custom Arctic provider adapter for providers without a built-in profile normalizer. */
99
+ export declare function arcticProvider(config: ArcticCustomProvider): ArcticCustomProvider;
100
+ export declare function listArcticProviders(): ArcticBuiltInProvider[];
101
+ //# sourceMappingURL=use-arctic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-arctic.d.ts","sourceRoot":"","sources":["../src/use-arctic.ts"],"names":[],"mappings":"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"}