@iqauth/sdk 2.0.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 +287 -0
- package/dist/browser-session.d.mts +12 -0
- package/dist/browser-session.d.ts +12 -0
- package/dist/browser-session.js +1812 -0
- package/dist/browser-session.mjs +28 -0
- package/dist/browser.d.mts +46 -0
- package/dist/browser.d.ts +46 -0
- package/dist/browser.js +768 -0
- package/dist/browser.mjs +47 -0
- package/dist/chunk-5HF3OBNO.mjs +189 -0
- package/dist/chunk-5WFR6Y33.mjs +59 -0
- package/dist/chunk-6I6RM4MN.mjs +51 -0
- package/dist/chunk-73R6BEGO.mjs +176 -0
- package/dist/chunk-E46DKOVI.mjs +632 -0
- package/dist/chunk-JQWYIIIS.mjs +1740 -0
- package/dist/chunk-X3K3WOBR.mjs +64 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +581 -0
- package/dist/cli/index.mjs +57 -0
- package/dist/client-C1DXfB8Z.d.mts +911 -0
- package/dist/client-CggvJmmm.d.ts +911 -0
- package/dist/dev-FUTJZSWN.mjs +56 -0
- package/dist/doctor-OHJRZBBT.mjs +89 -0
- package/dist/errors-CDdl24MP.d.mts +52 -0
- package/dist/errors-CDdl24MP.d.ts +52 -0
- package/dist/express-BKAXB5Nl.d.ts +61 -0
- package/dist/express-CpfyYTmw.d.mts +61 -0
- package/dist/express.d.mts +45 -0
- package/dist/express.d.ts +45 -0
- package/dist/express.js +2252 -0
- package/dist/express.mjs +122 -0
- package/dist/fastify.d.mts +23 -0
- package/dist/fastify.d.ts +23 -0
- package/dist/fastify.js +2062 -0
- package/dist/fastify.mjs +118 -0
- package/dist/hono.d.mts +22 -0
- package/dist/hono.d.ts +22 -0
- package/dist/hono.js +2051 -0
- package/dist/hono.mjs +107 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2070 -0
- package/dist/index.mjs +83 -0
- package/dist/init-LLCSQGNL.mjs +198 -0
- package/dist/keys-NLWFAOEM.mjs +63 -0
- package/dist/mobile.d.mts +11 -0
- package/dist/mobile.d.ts +11 -0
- package/dist/mobile.js +1809 -0
- package/dist/mobile.mjs +25 -0
- package/dist/next.d.mts +37 -0
- package/dist/next.d.ts +37 -0
- package/dist/next.js +2078 -0
- package/dist/next.mjs +130 -0
- package/dist/publishableKey-B5DIK81A.d.mts +24 -0
- package/dist/publishableKey-B5DIK81A.d.ts +24 -0
- package/dist/react.d.mts +196 -0
- package/dist/react.d.ts +196 -0
- package/dist/react.js +1457 -0
- package/dist/react.mjs +787 -0
- package/dist/server/handlers.d.mts +96 -0
- package/dist/server/handlers.d.ts +96 -0
- package/dist/server/handlers.js +243 -0
- package/dist/server/handlers.mjs +14 -0
- package/dist/server.d.mts +14 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.js +2195 -0
- package/dist/server.mjs +47 -0
- package/dist/service.d.mts +11 -0
- package/dist/service.d.ts +11 -0
- package/dist/service.js +1809 -0
- package/dist/service.mjs +25 -0
- package/dist/signIn-C8f6qVjD.d.mts +238 -0
- package/dist/signIn-Cy2lbEXb.d.ts +238 -0
- package/dist/types-Cxl3bQHt.d.mts +900 -0
- package/dist/types-Cxl3bQHt.d.ts +900 -0
- package/docs/APP_INTEGRATION_MATRIX.md +59 -0
- package/docs/BROWSER_SESSION_MIGRATION.md +69 -0
- package/docs/FRESH_IMPLEMENTATION_GUIDE.md +188 -0
- package/docs/TARBALL_RELEASE_WORKFLOW.md +98 -0
- package/docs/V1_TO_V2_UPGRADE_GUIDE.md +318 -0
- package/docs/guides/api-keys.md +130 -0
- package/docs/guides/app-registration.md +149 -0
- package/docs/guides/auth-flows.md +168 -0
- package/docs/guides/branding.md +160 -0
- package/docs/guides/entitlements.md +115 -0
- package/docs/guides/entity-hierarchy.md +200 -0
- package/docs/guides/error-handling.md +251 -0
- package/docs/guides/gdpr-compliance.md +123 -0
- package/docs/guides/invitations.md +143 -0
- package/docs/guides/mfa-enrollment.md +170 -0
- package/docs/guides/middleware-reference.md +205 -0
- package/docs/guides/mobile-native.md +110 -0
- package/docs/guides/roles-and-permissions.md +220 -0
- package/docs/guides/scoped-authorization.md +247 -0
- package/docs/guides/server-platform-integration.md +52 -0
- package/docs/guides/service-automation-integration.md +36 -0
- package/docs/guides/session-management.md +97 -0
- package/docs/guides/tenant-management.md +216 -0
- package/docs/guides/token-verification.md +178 -0
- package/docs/guides/user-management.md +184 -0
- package/docs/guides/webhooks.md +136 -0
- package/docs/integration-prompts/README.md +20 -0
- package/docs/integration-prompts/first-party-browser-app.md +29 -0
- package/docs/integration-prompts/install-from-tarball.md +41 -0
- package/docs/integration-prompts/migrate-from-local-packages-source.md +57 -0
- package/docs/integration-prompts/native-mobile-app.md +24 -0
- package/docs/integration-prompts/server-platform-app.md +20 -0
- package/docs/integration-prompts/service-automation-app.md +20 -0
- package/package.json +115 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-neutral helper handlers for the auto-mounted routes added by the
|
|
3
|
+
* @iqauth/sdk framework adapters. Each handler takes the parsed request
|
|
4
|
+
* inputs and returns a structured response that the adapter renders into
|
|
5
|
+
* the framework's native Response object.
|
|
6
|
+
*
|
|
7
|
+
* Three routes are exposed:
|
|
8
|
+
* POST /api/iqauth/callback — exchange an OIDC authorization code for tokens
|
|
9
|
+
* and set the iqauth_at + iqauth_rt cookies.
|
|
10
|
+
* POST /api/iqauth/refresh — rotate the refresh-token cookie and return a
|
|
11
|
+
* fresh access token (cookie + JSON).
|
|
12
|
+
* POST /api/iqauth/signout — clear the auth cookies and best-effort revoke
|
|
13
|
+
* the session at the issuer.
|
|
14
|
+
*
|
|
15
|
+
* The handlers never mutate global state. They only return cookie + body
|
|
16
|
+
* directives; cookie writes are performed by the adapter using the host
|
|
17
|
+
* framework's cookie API. This keeps adapters trivially thin and makes the
|
|
18
|
+
* handlers pure-functionally testable.
|
|
19
|
+
*/
|
|
20
|
+
interface SetCookieDirective {
|
|
21
|
+
name: string;
|
|
22
|
+
value: string;
|
|
23
|
+
/** Empty string to clear. */
|
|
24
|
+
maxAge: number;
|
|
25
|
+
httpOnly: boolean;
|
|
26
|
+
secure: boolean;
|
|
27
|
+
sameSite: "lax" | "strict" | "none";
|
|
28
|
+
path: string;
|
|
29
|
+
domain?: string;
|
|
30
|
+
}
|
|
31
|
+
interface HandlerResponse {
|
|
32
|
+
status: number;
|
|
33
|
+
body: Record<string, unknown>;
|
|
34
|
+
cookies: SetCookieDirective[];
|
|
35
|
+
}
|
|
36
|
+
interface IQAuthHelperConfig {
|
|
37
|
+
/** Required: pk_test_… or pk_live_… */
|
|
38
|
+
publishableKey: string;
|
|
39
|
+
/** Required for callback / refresh / signout against the issuer. */
|
|
40
|
+
secretKey?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Override the issuer URL. Auto-discovered from the publishable key when
|
|
43
|
+
* omitted (the key encodes its own issuer host).
|
|
44
|
+
*/
|
|
45
|
+
issuer?: string;
|
|
46
|
+
/** Override the access token cookie name. Defaults to `iqauth_at`. */
|
|
47
|
+
accessCookieName?: string;
|
|
48
|
+
/** Override the refresh token cookie name. Defaults to `iqauth_rt`. */
|
|
49
|
+
refreshCookieName?: string;
|
|
50
|
+
/** Cookie domain (e.g. `.example.com`). Defaults to host-only. */
|
|
51
|
+
cookieDomain?: string;
|
|
52
|
+
/** Cookie sameSite policy. Defaults to `lax`. */
|
|
53
|
+
sameSite?: "lax" | "strict" | "none";
|
|
54
|
+
/** Cookie secure flag. Defaults to true (set false for local http dev). */
|
|
55
|
+
secure?: boolean;
|
|
56
|
+
/** Cookie path. Defaults to `/`. */
|
|
57
|
+
cookiePath?: string;
|
|
58
|
+
/** Path of the OIDC token endpoint. */
|
|
59
|
+
tokenPath?: string;
|
|
60
|
+
/** Path of the auth refresh endpoint on the issuer. */
|
|
61
|
+
refreshPath?: string;
|
|
62
|
+
/** Path of the logout endpoint on the issuer. */
|
|
63
|
+
logoutPath?: string;
|
|
64
|
+
/** Optional fetch implementation override. */
|
|
65
|
+
fetchImpl?: typeof fetch;
|
|
66
|
+
}
|
|
67
|
+
interface ResolvedConfig extends Required<Omit<IQAuthHelperConfig, "secretKey" | "cookieDomain" | "issuer" | "fetchImpl">> {
|
|
68
|
+
secretKey?: string;
|
|
69
|
+
cookieDomain?: string;
|
|
70
|
+
issuer: string;
|
|
71
|
+
fetchImpl: typeof fetch;
|
|
72
|
+
appId: string;
|
|
73
|
+
tenantId: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Serialize a cookie directive to a Set-Cookie header value. Adapters that
|
|
77
|
+
* lack a typed cookie API (Hono, raw Node) use this; Express / Fastify /
|
|
78
|
+
* Next prefer their native cookie setters.
|
|
79
|
+
*/
|
|
80
|
+
declare function serializeCookie(d: SetCookieDirective): string;
|
|
81
|
+
/** POST /api/iqauth/callback — exchange an OIDC authorization code. */
|
|
82
|
+
declare function handleCallback(config: IQAuthHelperConfig, input: {
|
|
83
|
+
code?: string;
|
|
84
|
+
codeVerifier?: string;
|
|
85
|
+
redirectUri?: string;
|
|
86
|
+
}): Promise<HandlerResponse>;
|
|
87
|
+
/** POST /api/iqauth/refresh — rotate refresh + access cookies. */
|
|
88
|
+
declare function handleRefresh(config: IQAuthHelperConfig, input: {
|
|
89
|
+
refreshToken?: string;
|
|
90
|
+
}): Promise<HandlerResponse>;
|
|
91
|
+
/** POST /api/iqauth/signout — clear cookies and best-effort revoke at issuer. */
|
|
92
|
+
declare function handleSignout(config: IQAuthHelperConfig, input: {
|
|
93
|
+
accessToken?: string;
|
|
94
|
+
}): Promise<HandlerResponse>;
|
|
95
|
+
|
|
96
|
+
export { type HandlerResponse, type IQAuthHelperConfig, type ResolvedConfig as ResolvedIQAuthHelperConfig, type SetCookieDirective, handleCallback, handleRefresh, handleSignout, serializeCookie };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-neutral helper handlers for the auto-mounted routes added by the
|
|
3
|
+
* @iqauth/sdk framework adapters. Each handler takes the parsed request
|
|
4
|
+
* inputs and returns a structured response that the adapter renders into
|
|
5
|
+
* the framework's native Response object.
|
|
6
|
+
*
|
|
7
|
+
* Three routes are exposed:
|
|
8
|
+
* POST /api/iqauth/callback — exchange an OIDC authorization code for tokens
|
|
9
|
+
* and set the iqauth_at + iqauth_rt cookies.
|
|
10
|
+
* POST /api/iqauth/refresh — rotate the refresh-token cookie and return a
|
|
11
|
+
* fresh access token (cookie + JSON).
|
|
12
|
+
* POST /api/iqauth/signout — clear the auth cookies and best-effort revoke
|
|
13
|
+
* the session at the issuer.
|
|
14
|
+
*
|
|
15
|
+
* The handlers never mutate global state. They only return cookie + body
|
|
16
|
+
* directives; cookie writes are performed by the adapter using the host
|
|
17
|
+
* framework's cookie API. This keeps adapters trivially thin and makes the
|
|
18
|
+
* handlers pure-functionally testable.
|
|
19
|
+
*/
|
|
20
|
+
interface SetCookieDirective {
|
|
21
|
+
name: string;
|
|
22
|
+
value: string;
|
|
23
|
+
/** Empty string to clear. */
|
|
24
|
+
maxAge: number;
|
|
25
|
+
httpOnly: boolean;
|
|
26
|
+
secure: boolean;
|
|
27
|
+
sameSite: "lax" | "strict" | "none";
|
|
28
|
+
path: string;
|
|
29
|
+
domain?: string;
|
|
30
|
+
}
|
|
31
|
+
interface HandlerResponse {
|
|
32
|
+
status: number;
|
|
33
|
+
body: Record<string, unknown>;
|
|
34
|
+
cookies: SetCookieDirective[];
|
|
35
|
+
}
|
|
36
|
+
interface IQAuthHelperConfig {
|
|
37
|
+
/** Required: pk_test_… or pk_live_… */
|
|
38
|
+
publishableKey: string;
|
|
39
|
+
/** Required for callback / refresh / signout against the issuer. */
|
|
40
|
+
secretKey?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Override the issuer URL. Auto-discovered from the publishable key when
|
|
43
|
+
* omitted (the key encodes its own issuer host).
|
|
44
|
+
*/
|
|
45
|
+
issuer?: string;
|
|
46
|
+
/** Override the access token cookie name. Defaults to `iqauth_at`. */
|
|
47
|
+
accessCookieName?: string;
|
|
48
|
+
/** Override the refresh token cookie name. Defaults to `iqauth_rt`. */
|
|
49
|
+
refreshCookieName?: string;
|
|
50
|
+
/** Cookie domain (e.g. `.example.com`). Defaults to host-only. */
|
|
51
|
+
cookieDomain?: string;
|
|
52
|
+
/** Cookie sameSite policy. Defaults to `lax`. */
|
|
53
|
+
sameSite?: "lax" | "strict" | "none";
|
|
54
|
+
/** Cookie secure flag. Defaults to true (set false for local http dev). */
|
|
55
|
+
secure?: boolean;
|
|
56
|
+
/** Cookie path. Defaults to `/`. */
|
|
57
|
+
cookiePath?: string;
|
|
58
|
+
/** Path of the OIDC token endpoint. */
|
|
59
|
+
tokenPath?: string;
|
|
60
|
+
/** Path of the auth refresh endpoint on the issuer. */
|
|
61
|
+
refreshPath?: string;
|
|
62
|
+
/** Path of the logout endpoint on the issuer. */
|
|
63
|
+
logoutPath?: string;
|
|
64
|
+
/** Optional fetch implementation override. */
|
|
65
|
+
fetchImpl?: typeof fetch;
|
|
66
|
+
}
|
|
67
|
+
interface ResolvedConfig extends Required<Omit<IQAuthHelperConfig, "secretKey" | "cookieDomain" | "issuer" | "fetchImpl">> {
|
|
68
|
+
secretKey?: string;
|
|
69
|
+
cookieDomain?: string;
|
|
70
|
+
issuer: string;
|
|
71
|
+
fetchImpl: typeof fetch;
|
|
72
|
+
appId: string;
|
|
73
|
+
tenantId: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Serialize a cookie directive to a Set-Cookie header value. Adapters that
|
|
77
|
+
* lack a typed cookie API (Hono, raw Node) use this; Express / Fastify /
|
|
78
|
+
* Next prefer their native cookie setters.
|
|
79
|
+
*/
|
|
80
|
+
declare function serializeCookie(d: SetCookieDirective): string;
|
|
81
|
+
/** POST /api/iqauth/callback — exchange an OIDC authorization code. */
|
|
82
|
+
declare function handleCallback(config: IQAuthHelperConfig, input: {
|
|
83
|
+
code?: string;
|
|
84
|
+
codeVerifier?: string;
|
|
85
|
+
redirectUri?: string;
|
|
86
|
+
}): Promise<HandlerResponse>;
|
|
87
|
+
/** POST /api/iqauth/refresh — rotate refresh + access cookies. */
|
|
88
|
+
declare function handleRefresh(config: IQAuthHelperConfig, input: {
|
|
89
|
+
refreshToken?: string;
|
|
90
|
+
}): Promise<HandlerResponse>;
|
|
91
|
+
/** POST /api/iqauth/signout — clear cookies and best-effort revoke at issuer. */
|
|
92
|
+
declare function handleSignout(config: IQAuthHelperConfig, input: {
|
|
93
|
+
accessToken?: string;
|
|
94
|
+
}): Promise<HandlerResponse>;
|
|
95
|
+
|
|
96
|
+
export { type HandlerResponse, type IQAuthHelperConfig, type ResolvedConfig as ResolvedIQAuthHelperConfig, type SetCookieDirective, handleCallback, handleRefresh, handleSignout, serializeCookie };
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server/handlers.ts
|
|
21
|
+
var handlers_exports = {};
|
|
22
|
+
__export(handlers_exports, {
|
|
23
|
+
handleCallback: () => handleCallback,
|
|
24
|
+
handleRefresh: () => handleRefresh,
|
|
25
|
+
handleSignout: () => handleSignout,
|
|
26
|
+
serializeCookie: () => serializeCookie
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(handlers_exports);
|
|
29
|
+
|
|
30
|
+
// src/publishableKey.ts
|
|
31
|
+
function b64urlDecode(input) {
|
|
32
|
+
const pad = input.length % 4 === 0 ? "" : "=".repeat(4 - input.length % 4);
|
|
33
|
+
const normalized = input.replace(/-/g, "+").replace(/_/g, "/") + pad;
|
|
34
|
+
if (typeof atob === "function") {
|
|
35
|
+
const bin = atob(normalized);
|
|
36
|
+
const bytes = new Uint8Array(bin.length);
|
|
37
|
+
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
38
|
+
return new TextDecoder().decode(bytes);
|
|
39
|
+
}
|
|
40
|
+
const { Buffer: Buffer2 } = require("buffer");
|
|
41
|
+
return Buffer2.from(normalized, "base64").toString("utf8");
|
|
42
|
+
}
|
|
43
|
+
function parsePublishableKey(raw) {
|
|
44
|
+
if (typeof raw !== "string") return null;
|
|
45
|
+
const m = raw.match(/^pk_(test|live)_([A-Za-z0-9_-]+)$/);
|
|
46
|
+
if (!m) return null;
|
|
47
|
+
try {
|
|
48
|
+
const json = JSON.parse(b64urlDecode(m[2]));
|
|
49
|
+
if (!json || typeof json !== "object") return null;
|
|
50
|
+
if (typeof json.iss !== "string" || typeof json.appId !== "string" || typeof json.tenantId !== "string" || typeof json.kid !== "string") {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return { mode: m[1], iss: json.iss, appId: json.appId, tenantId: json.tenantId, kid: json.kid, raw };
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/server/handlers.ts
|
|
60
|
+
var ACCESS_TOKEN_TTL_SECONDS = 60 * 15;
|
|
61
|
+
var REFRESH_TOKEN_TTL_SECONDS = 60 * 60 * 24 * 30;
|
|
62
|
+
function resolve(config) {
|
|
63
|
+
const parsed = parsePublishableKey(config.publishableKey);
|
|
64
|
+
if (!parsed) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
"@iqauth/sdk: invalid publishable key passed to iqAuth helpers (expected pk_test_\u2026 or pk_live_\u2026)"
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const inferredIssuer = parsed.iss.startsWith("http") ? parsed.iss : `https://${parsed.iss}`;
|
|
70
|
+
return {
|
|
71
|
+
publishableKey: config.publishableKey,
|
|
72
|
+
secretKey: config.secretKey,
|
|
73
|
+
issuer: (config.issuer ?? inferredIssuer).replace(/\/+$/, ""),
|
|
74
|
+
accessCookieName: config.accessCookieName ?? "iqauth_at",
|
|
75
|
+
refreshCookieName: config.refreshCookieName ?? "iqauth_rt",
|
|
76
|
+
cookieDomain: config.cookieDomain,
|
|
77
|
+
sameSite: config.sameSite ?? "lax",
|
|
78
|
+
secure: config.secure ?? true,
|
|
79
|
+
cookiePath: config.cookiePath ?? "/",
|
|
80
|
+
tokenPath: config.tokenPath ?? "/oidc/token",
|
|
81
|
+
refreshPath: config.refreshPath ?? "/api/v1/auth/refresh",
|
|
82
|
+
logoutPath: config.logoutPath ?? "/api/v1/auth/logout",
|
|
83
|
+
fetchImpl: config.fetchImpl ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : (() => {
|
|
84
|
+
throw new Error("global fetch is unavailable; pass fetchImpl");
|
|
85
|
+
})),
|
|
86
|
+
appId: parsed.appId,
|
|
87
|
+
tenantId: parsed.tenantId
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function makeCookie(cfg, name, value, maxAge, httpOnly = true) {
|
|
91
|
+
return {
|
|
92
|
+
name,
|
|
93
|
+
value,
|
|
94
|
+
maxAge,
|
|
95
|
+
httpOnly,
|
|
96
|
+
secure: cfg.secure,
|
|
97
|
+
sameSite: cfg.sameSite,
|
|
98
|
+
path: cfg.cookiePath,
|
|
99
|
+
domain: cfg.cookieDomain
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function clearCookies(cfg) {
|
|
103
|
+
return [
|
|
104
|
+
makeCookie(cfg, cfg.accessCookieName, "", 0),
|
|
105
|
+
makeCookie(cfg, cfg.refreshCookieName, "", 0)
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
function serializeCookie(d) {
|
|
109
|
+
const parts = [`${d.name}=${encodeURIComponent(d.value)}`];
|
|
110
|
+
parts.push(`Path=${d.path}`);
|
|
111
|
+
if (d.domain) parts.push(`Domain=${d.domain}`);
|
|
112
|
+
parts.push(`Max-Age=${d.maxAge}`);
|
|
113
|
+
if (d.secure) parts.push("Secure");
|
|
114
|
+
if (d.httpOnly) parts.push("HttpOnly");
|
|
115
|
+
parts.push(`SameSite=${d.sameSite}`);
|
|
116
|
+
return parts.join("; ");
|
|
117
|
+
}
|
|
118
|
+
async function handleCallback(config, input) {
|
|
119
|
+
const cfg = resolve(config);
|
|
120
|
+
if (!input.code || !input.redirectUri) {
|
|
121
|
+
return {
|
|
122
|
+
status: 400,
|
|
123
|
+
body: { success: false, error: { code: "VALIDATION_ERROR", message: "code and redirectUri are required" } },
|
|
124
|
+
cookies: []
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (!cfg.secretKey) {
|
|
128
|
+
return {
|
|
129
|
+
status: 500,
|
|
130
|
+
body: { success: false, error: { code: "INTERNAL_ERROR", message: "secretKey is required for the callback handler" } },
|
|
131
|
+
cookies: []
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const body = new URLSearchParams({
|
|
135
|
+
grant_type: "authorization_code",
|
|
136
|
+
code: input.code,
|
|
137
|
+
redirect_uri: input.redirectUri,
|
|
138
|
+
client_id: cfg.appId
|
|
139
|
+
});
|
|
140
|
+
if (input.codeVerifier) body.set("code_verifier", input.codeVerifier);
|
|
141
|
+
const res = await cfg.fetchImpl(`${cfg.issuer}${cfg.tokenPath}`, {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: {
|
|
144
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
145
|
+
Authorization: `Basic ${typeof btoa === "function" ? btoa(`${cfg.appId}:${cfg.secretKey}`) : Buffer.from(`${cfg.appId}:${cfg.secretKey}`).toString("base64")}`
|
|
146
|
+
},
|
|
147
|
+
body: body.toString()
|
|
148
|
+
});
|
|
149
|
+
const json = await res.json().catch(() => ({}));
|
|
150
|
+
if (!res.ok || !json.access_token) {
|
|
151
|
+
return {
|
|
152
|
+
status: res.status || 502,
|
|
153
|
+
body: {
|
|
154
|
+
success: false,
|
|
155
|
+
error: {
|
|
156
|
+
code: json.error || "OIDC_EXCHANGE_FAILED",
|
|
157
|
+
message: json.error_description || "Authorization code exchange failed"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
cookies: []
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const cookies = [];
|
|
164
|
+
cookies.push(
|
|
165
|
+
makeCookie(cfg, cfg.accessCookieName, json.access_token, json.expires_in ?? ACCESS_TOKEN_TTL_SECONDS)
|
|
166
|
+
);
|
|
167
|
+
if (json.refresh_token) {
|
|
168
|
+
cookies.push(makeCookie(cfg, cfg.refreshCookieName, json.refresh_token, REFRESH_TOKEN_TTL_SECONDS));
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
status: 200,
|
|
172
|
+
body: { success: true, data: { authenticated: true } },
|
|
173
|
+
cookies
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
async function handleRefresh(config, input) {
|
|
177
|
+
const cfg = resolve(config);
|
|
178
|
+
const refreshToken = input.refreshToken;
|
|
179
|
+
if (!refreshToken) {
|
|
180
|
+
return {
|
|
181
|
+
status: 401,
|
|
182
|
+
body: { success: false, error: { code: "TOKEN_INVALID", message: "Missing refresh token" } },
|
|
183
|
+
cookies: clearCookies(cfg)
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const res = await cfg.fetchImpl(`${cfg.issuer}${cfg.refreshPath}`, {
|
|
187
|
+
method: "POST",
|
|
188
|
+
headers: { "Content-Type": "application/json" },
|
|
189
|
+
body: JSON.stringify({ refreshToken })
|
|
190
|
+
});
|
|
191
|
+
const json = await res.json().catch(() => ({}));
|
|
192
|
+
if (!res.ok || !json.success || !json.data?.accessToken) {
|
|
193
|
+
return {
|
|
194
|
+
status: res.status || 401,
|
|
195
|
+
body: {
|
|
196
|
+
success: false,
|
|
197
|
+
error: {
|
|
198
|
+
code: json.error?.code || "TOKEN_INVALID",
|
|
199
|
+
message: json.error?.message || "Refresh failed"
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
cookies: clearCookies(cfg)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const cookies = [
|
|
206
|
+
makeCookie(cfg, cfg.accessCookieName, json.data.accessToken, ACCESS_TOKEN_TTL_SECONDS)
|
|
207
|
+
];
|
|
208
|
+
if (json.data.refreshToken) {
|
|
209
|
+
cookies.push(makeCookie(cfg, cfg.refreshCookieName, json.data.refreshToken, REFRESH_TOKEN_TTL_SECONDS));
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
status: 200,
|
|
213
|
+
body: { success: true, data: { accessToken: json.data.accessToken } },
|
|
214
|
+
cookies
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
async function handleSignout(config, input) {
|
|
218
|
+
const cfg = resolve(config);
|
|
219
|
+
if (input.accessToken) {
|
|
220
|
+
try {
|
|
221
|
+
await cfg.fetchImpl(`${cfg.issuer}${cfg.logoutPath}`, {
|
|
222
|
+
method: "POST",
|
|
223
|
+
headers: {
|
|
224
|
+
"Content-Type": "application/json",
|
|
225
|
+
Authorization: `Bearer ${input.accessToken}`
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
status: 200,
|
|
233
|
+
body: { success: true, data: { signedOut: true } },
|
|
234
|
+
cookies: clearCookies(cfg)
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
238
|
+
0 && (module.exports = {
|
|
239
|
+
handleCallback,
|
|
240
|
+
handleRefresh,
|
|
241
|
+
handleSignout,
|
|
242
|
+
serializeCookie
|
|
243
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleCallback,
|
|
3
|
+
handleRefresh,
|
|
4
|
+
handleSignout,
|
|
5
|
+
serializeCookie
|
|
6
|
+
} from "../chunk-5HF3OBNO.mjs";
|
|
7
|
+
import "../chunk-5WFR6Y33.mjs";
|
|
8
|
+
import "../chunk-Y6FXYEAI.mjs";
|
|
9
|
+
export {
|
|
10
|
+
handleCallback,
|
|
11
|
+
handleRefresh,
|
|
12
|
+
handleSignout,
|
|
13
|
+
serializeCookie
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { b as IQAuthTokenClientConfig, N as ExpressMiddlewareOptions, Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.mjs';
|
|
2
|
+
import { I as IQAuthClient } from './client-C1DXfB8Z.mjs';
|
|
3
|
+
export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.mjs';
|
|
4
|
+
export { C as CookieAwareMiddlewareOptions, D as DEFAULT_ACCESS_COOKIE, a as DEFAULT_REFRESH_COOKIE, i as iqAuthMiddleware } from './express-CpfyYTmw.mjs';
|
|
5
|
+
export { HandlerResponse, IQAuthHelperConfig, SetCookieDirective, handleCallback, handleRefresh, handleSignout, serializeCookie } from './server/handlers.mjs';
|
|
6
|
+
import 'jsonwebtoken';
|
|
7
|
+
|
|
8
|
+
declare class ServerIQAuthClient extends IQAuthClient {
|
|
9
|
+
constructor(config: IQAuthTokenClientConfig);
|
|
10
|
+
middleware(options?: ExpressMiddlewareOptions): (req: IQAuthRequestLike, res: IQAuthResponseLike, next: IQAuthNextFunction) => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
declare function createServerClient(config: IQAuthTokenClientConfig): ServerIQAuthClient;
|
|
13
|
+
|
|
14
|
+
export { ExpressMiddlewareOptions, IQAuthClient, IQAuthTokenClientConfig, ServerIQAuthClient, createServerClient };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { b as IQAuthTokenClientConfig, N as ExpressMiddlewareOptions, Q as IQAuthRequestLike, R as IQAuthResponseLike, V as IQAuthNextFunction } from './types-Cxl3bQHt.js';
|
|
2
|
+
import { I as IQAuthClient } from './client-CggvJmmm.js';
|
|
3
|
+
export { E as ErrorCodes, I as IQAuthError } from './errors-CDdl24MP.js';
|
|
4
|
+
export { C as CookieAwareMiddlewareOptions, D as DEFAULT_ACCESS_COOKIE, a as DEFAULT_REFRESH_COOKIE, i as iqAuthMiddleware } from './express-BKAXB5Nl.js';
|
|
5
|
+
export { HandlerResponse, IQAuthHelperConfig, SetCookieDirective, handleCallback, handleRefresh, handleSignout, serializeCookie } from './server/handlers.js';
|
|
6
|
+
import 'jsonwebtoken';
|
|
7
|
+
|
|
8
|
+
declare class ServerIQAuthClient extends IQAuthClient {
|
|
9
|
+
constructor(config: IQAuthTokenClientConfig);
|
|
10
|
+
middleware(options?: ExpressMiddlewareOptions): (req: IQAuthRequestLike, res: IQAuthResponseLike, next: IQAuthNextFunction) => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
declare function createServerClient(config: IQAuthTokenClientConfig): ServerIQAuthClient;
|
|
13
|
+
|
|
14
|
+
export { ExpressMiddlewareOptions, IQAuthClient, IQAuthTokenClientConfig, ServerIQAuthClient, createServerClient };
|