@ovixa/auth-client 0.1.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/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +484 -0
- package/dist/chunk-UHRF6AFJ.js +544 -0
- package/dist/chunk-UHRF6AFJ.js.map +1 -0
- package/dist/chunk-Y5NJCTZO.js +143 -0
- package/dist/chunk-Y5NJCTZO.js.map +1 -0
- package/dist/index.d.ts +498 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/astro.d.ts +155 -0
- package/dist/middleware/astro.js +75 -0
- package/dist/middleware/astro.js.map +1 -0
- package/dist/middleware/express.d.ts +197 -0
- package/dist/middleware/express.js +87 -0
- package/dist/middleware/express.js.map +1 -0
- package/dist/types-Czfah64-.d.ts +57 -0
- package/package.json +78 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { TokenResponse } from '../index.js';
|
|
2
|
+
import { A as AuthMiddlewareConfig, a as AuthContext, C as CookieOptions } from '../types-Czfah64-.js';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Astro middleware for @ovixa/auth-client
|
|
7
|
+
*
|
|
8
|
+
* Provides authentication middleware for Astro applications using cookie-based sessions.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // src/middleware.ts
|
|
13
|
+
* import { createAstroAuth } from '@ovixa/auth-client/astro';
|
|
14
|
+
* import { auth } from './lib/auth';
|
|
15
|
+
*
|
|
16
|
+
* export const onRequest = createAstroAuth({
|
|
17
|
+
* auth,
|
|
18
|
+
* publicRoutes: ['/', '/login', '/signup', '/api/public/*'],
|
|
19
|
+
* loginRedirect: '/login',
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Access in pages/layouts:
|
|
23
|
+
* const { user, isAuthenticated } = Astro.locals.auth;
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Astro APIContext type (minimal subset we need).
|
|
29
|
+
* We use this instead of importing from 'astro' to avoid requiring it as a dependency.
|
|
30
|
+
*/
|
|
31
|
+
interface AstroAPIContext {
|
|
32
|
+
url: URL;
|
|
33
|
+
cookies: AstroCookies;
|
|
34
|
+
locals: AstroLocals;
|
|
35
|
+
redirect: (path: string, status?: number) => Response;
|
|
36
|
+
}
|
|
37
|
+
interface AstroCookies {
|
|
38
|
+
get(name: string): {
|
|
39
|
+
value: string;
|
|
40
|
+
} | undefined;
|
|
41
|
+
set(name: string, value: string, options?: AstroCookieSetOptions): void;
|
|
42
|
+
delete(name: string, options?: AstroCookieDeleteOptions): void;
|
|
43
|
+
}
|
|
44
|
+
interface AstroCookieSetOptions {
|
|
45
|
+
path?: string;
|
|
46
|
+
secure?: boolean;
|
|
47
|
+
httpOnly?: boolean;
|
|
48
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
49
|
+
domain?: string;
|
|
50
|
+
maxAge?: number;
|
|
51
|
+
expires?: Date;
|
|
52
|
+
}
|
|
53
|
+
interface AstroCookieDeleteOptions {
|
|
54
|
+
path?: string;
|
|
55
|
+
domain?: string;
|
|
56
|
+
}
|
|
57
|
+
interface AstroLocals {
|
|
58
|
+
auth?: AuthContext;
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Astro middleware handler type.
|
|
63
|
+
*/
|
|
64
|
+
type AstroMiddlewareHandler = (context: AstroAPIContext, next: () => Promise<Response>) => Promise<Response>;
|
|
65
|
+
/**
|
|
66
|
+
* Create Astro authentication middleware.
|
|
67
|
+
*
|
|
68
|
+
* This middleware:
|
|
69
|
+
* - Checks authentication status from cookies on each request
|
|
70
|
+
* - Automatically refreshes expired access tokens using refresh tokens
|
|
71
|
+
* - Sets `Astro.locals.auth` with the authentication context
|
|
72
|
+
* - Optionally redirects unauthenticated requests to a login page
|
|
73
|
+
* - Allows public routes to bypass authentication
|
|
74
|
+
*
|
|
75
|
+
* @param config - Middleware configuration
|
|
76
|
+
* @returns Astro middleware handler
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // src/middleware.ts
|
|
81
|
+
* import { createAstroAuth } from '@ovixa/auth-client/astro';
|
|
82
|
+
* import { OvixaAuth } from '@ovixa/auth-client';
|
|
83
|
+
*
|
|
84
|
+
* const auth = new OvixaAuth({
|
|
85
|
+
* authUrl: import.meta.env.AUTH_URL,
|
|
86
|
+
* realmId: import.meta.env.AUTH_REALM_ID,
|
|
87
|
+
* });
|
|
88
|
+
*
|
|
89
|
+
* export const onRequest = createAstroAuth({
|
|
90
|
+
* auth,
|
|
91
|
+
* publicRoutes: ['/', '/login', '/signup'],
|
|
92
|
+
* loginRedirect: '/login',
|
|
93
|
+
* cookies: {
|
|
94
|
+
* secure: import.meta.env.PROD,
|
|
95
|
+
* },
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function createAstroAuth(config: AuthMiddlewareConfig): AstroMiddlewareHandler;
|
|
100
|
+
/**
|
|
101
|
+
* Set authentication cookies after login.
|
|
102
|
+
*
|
|
103
|
+
* Call this after a successful login to store tokens in cookies.
|
|
104
|
+
*
|
|
105
|
+
* @param context - Astro API context (from Astro global or API route)
|
|
106
|
+
* @param tokens - Token response from login/verify/OAuth callback
|
|
107
|
+
* @param cookieOptions - Optional cookie configuration overrides
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* // src/pages/api/login.ts
|
|
112
|
+
* import { setAstroAuthCookies } from '@ovixa/auth-client/astro';
|
|
113
|
+
* import { auth } from '../../lib/auth';
|
|
114
|
+
*
|
|
115
|
+
* export async function POST({ request, cookies }: APIContext) {
|
|
116
|
+
* const { email, password } = await request.json();
|
|
117
|
+
* const tokens = await auth.login({ email, password });
|
|
118
|
+
*
|
|
119
|
+
* setAstroAuthCookies({ cookies }, tokens);
|
|
120
|
+
*
|
|
121
|
+
* return new Response(JSON.stringify({ success: true }));
|
|
122
|
+
* }
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
declare function setAstroAuthCookies(context: Pick<AstroAPIContext, 'cookies'>, tokens: TokenResponse, cookieOptions?: CookieOptions): void;
|
|
126
|
+
/**
|
|
127
|
+
* Clear authentication cookies on logout.
|
|
128
|
+
*
|
|
129
|
+
* Call this to log out the user by removing their session cookies.
|
|
130
|
+
*
|
|
131
|
+
* @param context - Astro API context
|
|
132
|
+
* @param cookieOptions - Optional cookie configuration overrides
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* // src/pages/api/logout.ts
|
|
137
|
+
* import { clearAstroAuthCookies } from '@ovixa/auth-client/astro';
|
|
138
|
+
* import { auth } from '../../lib/auth';
|
|
139
|
+
*
|
|
140
|
+
* export async function POST({ cookies, locals }: APIContext) {
|
|
141
|
+
* // Revoke refresh token on server
|
|
142
|
+
* if (locals.auth?.session?.refreshToken) {
|
|
143
|
+
* await auth.logout(locals.auth.session.refreshToken);
|
|
144
|
+
* }
|
|
145
|
+
*
|
|
146
|
+
* // Clear cookies
|
|
147
|
+
* clearAstroAuthCookies({ cookies });
|
|
148
|
+
*
|
|
149
|
+
* return new Response(JSON.stringify({ success: true }));
|
|
150
|
+
* }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
declare function clearAstroAuthCookies(context: Pick<AstroAPIContext, 'cookies'>, cookieOptions?: CookieOptions): void;
|
|
154
|
+
|
|
155
|
+
export { AuthContext, AuthMiddlewareConfig, CookieOptions, clearAstroAuthCookies, createAstroAuth, setAstroAuthCookies };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkAuth,
|
|
3
|
+
clearAuthCookies,
|
|
4
|
+
isPublicRoute,
|
|
5
|
+
setAuthCookies
|
|
6
|
+
} from "../chunk-Y5NJCTZO.js";
|
|
7
|
+
import "../chunk-UHRF6AFJ.js";
|
|
8
|
+
|
|
9
|
+
// src/middleware/astro.ts
|
|
10
|
+
var AstroCookieAdapter = class {
|
|
11
|
+
constructor(cookies) {
|
|
12
|
+
this.cookies = cookies;
|
|
13
|
+
}
|
|
14
|
+
getCookie(name) {
|
|
15
|
+
return this.cookies.get(name)?.value;
|
|
16
|
+
}
|
|
17
|
+
setCookie(name, value, options) {
|
|
18
|
+
this.cookies.set(name, value, {
|
|
19
|
+
path: options.path,
|
|
20
|
+
secure: options.secure,
|
|
21
|
+
httpOnly: options.httpOnly,
|
|
22
|
+
sameSite: options.sameSite,
|
|
23
|
+
domain: options.domain,
|
|
24
|
+
maxAge: options.maxAge,
|
|
25
|
+
expires: options.expires
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
deleteCookie(name, options) {
|
|
29
|
+
this.cookies.delete(name, {
|
|
30
|
+
path: options.path,
|
|
31
|
+
domain: options.domain
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
function createAstroAuth(config) {
|
|
36
|
+
const { auth, cookies, publicRoutes = [], loginRedirect, autoRefresh = true } = config;
|
|
37
|
+
return async (context, next) => {
|
|
38
|
+
const path = context.url.pathname;
|
|
39
|
+
const isPublic = isPublicRoute(path, publicRoutes);
|
|
40
|
+
const adapter = new AstroCookieAdapter(context.cookies);
|
|
41
|
+
const result = await checkAuth(auth, adapter, cookies, autoRefresh);
|
|
42
|
+
if (result.newTokens) {
|
|
43
|
+
setAuthCookies(adapter, result.newTokens, cookies);
|
|
44
|
+
}
|
|
45
|
+
context.locals.auth = result.context;
|
|
46
|
+
if (result.context.isAuthenticated || isPublic) {
|
|
47
|
+
return next();
|
|
48
|
+
}
|
|
49
|
+
if (loginRedirect) {
|
|
50
|
+
const returnUrl = encodeURIComponent(context.url.pathname + context.url.search);
|
|
51
|
+
const redirectUrl = `${loginRedirect}?returnUrl=${returnUrl}`;
|
|
52
|
+
return context.redirect(redirectUrl, 302);
|
|
53
|
+
}
|
|
54
|
+
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
|
55
|
+
status: 401,
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "application/json"
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function setAstroAuthCookies(context, tokens, cookieOptions) {
|
|
63
|
+
const adapter = new AstroCookieAdapter(context.cookies);
|
|
64
|
+
setAuthCookies(adapter, tokens, cookieOptions);
|
|
65
|
+
}
|
|
66
|
+
function clearAstroAuthCookies(context, cookieOptions) {
|
|
67
|
+
const adapter = new AstroCookieAdapter(context.cookies);
|
|
68
|
+
clearAuthCookies(adapter, cookieOptions);
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
clearAstroAuthCookies,
|
|
72
|
+
createAstroAuth,
|
|
73
|
+
setAstroAuthCookies
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=astro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/middleware/astro.ts"],"sourcesContent":["/**\n * Astro middleware for @ovixa/auth-client\n *\n * Provides authentication middleware for Astro applications using cookie-based sessions.\n *\n * @example\n * ```typescript\n * // src/middleware.ts\n * import { createAstroAuth } from '@ovixa/auth-client/astro';\n * import { auth } from './lib/auth';\n *\n * export const onRequest = createAstroAuth({\n * auth,\n * publicRoutes: ['/', '/login', '/signup', '/api/public/*'],\n * loginRedirect: '/login',\n * });\n *\n * // Access in pages/layouts:\n * const { user, isAuthenticated } = Astro.locals.auth;\n * ```\n */\n\nimport type { TokenResponse } from '../index.js';\nimport type {\n AuthMiddlewareConfig,\n AuthContext,\n CookieAdapter,\n SetCookieOptions,\n DeleteCookieOptions,\n CookieOptions,\n} from './types.js';\nimport { isPublicRoute } from './types.js';\nimport {\n checkAuth,\n setAuthCookies as coreSetAuthCookies,\n clearAuthCookies as coreClearAuthCookies,\n} from './core.js';\n\n/**\n * Astro APIContext type (minimal subset we need).\n * We use this instead of importing from 'astro' to avoid requiring it as a dependency.\n */\ninterface AstroAPIContext {\n url: URL;\n cookies: AstroCookies;\n locals: AstroLocals;\n redirect: (path: string, status?: number) => Response;\n}\n\ninterface AstroCookies {\n get(name: string): { value: string } | undefined;\n set(name: string, value: string, options?: AstroCookieSetOptions): void;\n delete(name: string, options?: AstroCookieDeleteOptions): void;\n}\n\ninterface AstroCookieSetOptions {\n path?: string;\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: 'strict' | 'lax' | 'none';\n domain?: string;\n maxAge?: number;\n expires?: Date;\n}\n\ninterface AstroCookieDeleteOptions {\n path?: string;\n domain?: string;\n}\n\ninterface AstroLocals {\n auth?: AuthContext;\n [key: string]: unknown;\n}\n\n/**\n * Astro middleware handler type.\n */\ntype AstroMiddlewareHandler = (\n context: AstroAPIContext,\n next: () => Promise<Response>\n) => Promise<Response>;\n\n/**\n * Cookie adapter for Astro's cookie API.\n */\nclass AstroCookieAdapter implements CookieAdapter {\n constructor(private cookies: AstroCookies) {}\n\n getCookie(name: string): string | undefined {\n return this.cookies.get(name)?.value;\n }\n\n setCookie(name: string, value: string, options: SetCookieOptions): void {\n this.cookies.set(name, value, {\n path: options.path,\n secure: options.secure,\n httpOnly: options.httpOnly,\n sameSite: options.sameSite,\n domain: options.domain,\n maxAge: options.maxAge,\n expires: options.expires,\n });\n }\n\n deleteCookie(name: string, options: DeleteCookieOptions): void {\n this.cookies.delete(name, {\n path: options.path,\n domain: options.domain,\n });\n }\n}\n\n/**\n * Create Astro authentication middleware.\n *\n * This middleware:\n * - Checks authentication status from cookies on each request\n * - Automatically refreshes expired access tokens using refresh tokens\n * - Sets `Astro.locals.auth` with the authentication context\n * - Optionally redirects unauthenticated requests to a login page\n * - Allows public routes to bypass authentication\n *\n * @param config - Middleware configuration\n * @returns Astro middleware handler\n *\n * @example\n * ```typescript\n * // src/middleware.ts\n * import { createAstroAuth } from '@ovixa/auth-client/astro';\n * import { OvixaAuth } from '@ovixa/auth-client';\n *\n * const auth = new OvixaAuth({\n * authUrl: import.meta.env.AUTH_URL,\n * realmId: import.meta.env.AUTH_REALM_ID,\n * });\n *\n * export const onRequest = createAstroAuth({\n * auth,\n * publicRoutes: ['/', '/login', '/signup'],\n * loginRedirect: '/login',\n * cookies: {\n * secure: import.meta.env.PROD,\n * },\n * });\n * ```\n */\nexport function createAstroAuth(config: AuthMiddlewareConfig): AstroMiddlewareHandler {\n const { auth, cookies, publicRoutes = [], loginRedirect, autoRefresh = true } = config;\n\n return async (context: AstroAPIContext, next: () => Promise<Response>): Promise<Response> => {\n const path = context.url.pathname;\n\n // Check if this is a public route\n const isPublic = isPublicRoute(path, publicRoutes);\n\n // Create cookie adapter\n const adapter = new AstroCookieAdapter(context.cookies);\n\n // Check authentication status\n const result = await checkAuth(auth, adapter, cookies, autoRefresh);\n\n // If tokens were refreshed, update cookies\n if (result.newTokens) {\n coreSetAuthCookies(adapter, result.newTokens, cookies);\n }\n\n // Set auth context in locals\n context.locals.auth = result.context;\n\n // If authenticated or public route, continue\n if (result.context.isAuthenticated || isPublic) {\n return next();\n }\n\n // Not authenticated and not public - redirect or return 401\n if (loginRedirect) {\n // Add return URL as query param for redirect after login\n const returnUrl = encodeURIComponent(context.url.pathname + context.url.search);\n const redirectUrl = `${loginRedirect}?returnUrl=${returnUrl}`;\n return context.redirect(redirectUrl, 302);\n }\n\n // Return 401 Unauthorized\n return new Response(JSON.stringify({ error: 'Unauthorized' }), {\n status: 401,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n };\n}\n\n/**\n * Set authentication cookies after login.\n *\n * Call this after a successful login to store tokens in cookies.\n *\n * @param context - Astro API context (from Astro global or API route)\n * @param tokens - Token response from login/verify/OAuth callback\n * @param cookieOptions - Optional cookie configuration overrides\n *\n * @example\n * ```typescript\n * // src/pages/api/login.ts\n * import { setAstroAuthCookies } from '@ovixa/auth-client/astro';\n * import { auth } from '../../lib/auth';\n *\n * export async function POST({ request, cookies }: APIContext) {\n * const { email, password } = await request.json();\n * const tokens = await auth.login({ email, password });\n *\n * setAstroAuthCookies({ cookies }, tokens);\n *\n * return new Response(JSON.stringify({ success: true }));\n * }\n * ```\n */\nexport function setAstroAuthCookies(\n context: Pick<AstroAPIContext, 'cookies'>,\n tokens: TokenResponse,\n cookieOptions?: CookieOptions\n): void {\n const adapter = new AstroCookieAdapter(context.cookies);\n coreSetAuthCookies(adapter, tokens, cookieOptions);\n}\n\n/**\n * Clear authentication cookies on logout.\n *\n * Call this to log out the user by removing their session cookies.\n *\n * @param context - Astro API context\n * @param cookieOptions - Optional cookie configuration overrides\n *\n * @example\n * ```typescript\n * // src/pages/api/logout.ts\n * import { clearAstroAuthCookies } from '@ovixa/auth-client/astro';\n * import { auth } from '../../lib/auth';\n *\n * export async function POST({ cookies, locals }: APIContext) {\n * // Revoke refresh token on server\n * if (locals.auth?.session?.refreshToken) {\n * await auth.logout(locals.auth.session.refreshToken);\n * }\n *\n * // Clear cookies\n * clearAstroAuthCookies({ cookies });\n *\n * return new Response(JSON.stringify({ success: true }));\n * }\n * ```\n */\nexport function clearAstroAuthCookies(\n context: Pick<AstroAPIContext, 'cookies'>,\n cookieOptions?: CookieOptions\n): void {\n const adapter = new AstroCookieAdapter(context.cookies);\n coreClearAuthCookies(adapter, cookieOptions);\n}\n\n// Re-export types for convenience\nexport type { AuthMiddlewareConfig, AuthContext, CookieOptions } from './types.js';\n"],"mappings":";;;;;;;;;AAsFA,IAAM,qBAAN,MAAkD;AAAA,EAChD,YAAoB,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAE5C,UAAU,MAAkC;AAC1C,WAAO,KAAK,QAAQ,IAAI,IAAI,GAAG;AAAA,EACjC;AAAA,EAEA,UAAU,MAAc,OAAe,SAAiC;AACtE,SAAK,QAAQ,IAAI,MAAM,OAAO;AAAA,MAC5B,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,SAAS,QAAQ;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,MAAc,SAAoC;AAC7D,SAAK,QAAQ,OAAO,MAAM;AAAA,MACxB,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AACF;AAoCO,SAAS,gBAAgB,QAAsD;AACpF,QAAM,EAAE,MAAM,SAAS,eAAe,CAAC,GAAG,eAAe,cAAc,KAAK,IAAI;AAEhF,SAAO,OAAO,SAA0B,SAAqD;AAC3F,UAAM,OAAO,QAAQ,IAAI;AAGzB,UAAM,WAAW,cAAc,MAAM,YAAY;AAGjD,UAAM,UAAU,IAAI,mBAAmB,QAAQ,OAAO;AAGtD,UAAM,SAAS,MAAM,UAAU,MAAM,SAAS,SAAS,WAAW;AAGlE,QAAI,OAAO,WAAW;AACpB,qBAAmB,SAAS,OAAO,WAAW,OAAO;AAAA,IACvD;AAGA,YAAQ,OAAO,OAAO,OAAO;AAG7B,QAAI,OAAO,QAAQ,mBAAmB,UAAU;AAC9C,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,eAAe;AAEjB,YAAM,YAAY,mBAAmB,QAAQ,IAAI,WAAW,QAAQ,IAAI,MAAM;AAC9E,YAAM,cAAc,GAAG,aAAa,cAAc,SAAS;AAC3D,aAAO,QAAQ,SAAS,aAAa,GAAG;AAAA,IAC1C;AAGA,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,GAAG;AAAA,MAC7D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AA2BO,SAAS,oBACd,SACA,QACA,eACM;AACN,QAAM,UAAU,IAAI,mBAAmB,QAAQ,OAAO;AACtD,iBAAmB,SAAS,QAAQ,aAAa;AACnD;AA6BO,SAAS,sBACd,SACA,eACM;AACN,QAAM,UAAU,IAAI,mBAAmB,QAAQ,OAAO;AACtD,mBAAqB,SAAS,aAAa;AAC7C;","names":[]}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { TokenResponse } from '../index.js';
|
|
2
|
+
import { A as AuthMiddlewareConfig, a as AuthContext, C as CookieOptions } from '../types-Czfah64-.js';
|
|
3
|
+
import 'jose';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Express middleware for @ovixa/auth-client
|
|
7
|
+
*
|
|
8
|
+
* Provides authentication middleware for Express applications using cookie-based sessions.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import express from 'express';
|
|
13
|
+
* import cookieParser from 'cookie-parser';
|
|
14
|
+
* import { createExpressAuth, requireAuth } from '@ovixa/auth-client/express';
|
|
15
|
+
* import { auth } from './lib/auth';
|
|
16
|
+
*
|
|
17
|
+
* const app = express();
|
|
18
|
+
* app.use(cookieParser());
|
|
19
|
+
* app.use(createExpressAuth({
|
|
20
|
+
* auth,
|
|
21
|
+
* publicRoutes: ['/', '/login', '/signup', '/api/public/*'],
|
|
22
|
+
* loginRedirect: '/login',
|
|
23
|
+
* }));
|
|
24
|
+
*
|
|
25
|
+
* // Protected routes
|
|
26
|
+
* app.get('/api/me', requireAuth(), (req, res) => {
|
|
27
|
+
* res.json({ user: req.auth.user });
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Express Request type (minimal subset we need).
|
|
34
|
+
* We use this instead of importing from 'express' to avoid requiring it as a dependency.
|
|
35
|
+
*/
|
|
36
|
+
interface ExpressRequest {
|
|
37
|
+
path: string;
|
|
38
|
+
url: string;
|
|
39
|
+
originalUrl: string;
|
|
40
|
+
cookies: Record<string, string>;
|
|
41
|
+
auth?: AuthContext;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Express Response type (minimal subset we need).
|
|
45
|
+
*/
|
|
46
|
+
interface ExpressResponse {
|
|
47
|
+
cookie(name: string, value: string, options?: ExpressCookieOptions): this;
|
|
48
|
+
clearCookie(name: string, options?: ExpressClearCookieOptions): this;
|
|
49
|
+
redirect(url: string): void;
|
|
50
|
+
redirect(status: number, url: string): void;
|
|
51
|
+
status(code: number): this;
|
|
52
|
+
json(body: unknown): this;
|
|
53
|
+
}
|
|
54
|
+
interface ExpressCookieOptions {
|
|
55
|
+
path?: string;
|
|
56
|
+
secure?: boolean;
|
|
57
|
+
httpOnly?: boolean;
|
|
58
|
+
sameSite?: 'strict' | 'lax' | 'none' | boolean;
|
|
59
|
+
domain?: string;
|
|
60
|
+
maxAge?: number;
|
|
61
|
+
expires?: Date;
|
|
62
|
+
}
|
|
63
|
+
interface ExpressClearCookieOptions {
|
|
64
|
+
path?: string;
|
|
65
|
+
domain?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Express next function.
|
|
69
|
+
*/
|
|
70
|
+
type ExpressNextFunction = (err?: unknown) => void;
|
|
71
|
+
/**
|
|
72
|
+
* Express middleware handler type.
|
|
73
|
+
*/
|
|
74
|
+
type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void | Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Create Express authentication middleware.
|
|
77
|
+
*
|
|
78
|
+
* This middleware:
|
|
79
|
+
* - Checks authentication status from cookies on each request
|
|
80
|
+
* - Automatically refreshes expired access tokens using refresh tokens
|
|
81
|
+
* - Sets `req.auth` with the authentication context
|
|
82
|
+
* - Optionally redirects unauthenticated requests to a login page
|
|
83
|
+
* - Allows public routes to bypass authentication
|
|
84
|
+
*
|
|
85
|
+
* **Note:** Requires `cookie-parser` middleware to be installed and used before this middleware.
|
|
86
|
+
*
|
|
87
|
+
* @param config - Middleware configuration
|
|
88
|
+
* @returns Express middleware
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* import express from 'express';
|
|
93
|
+
* import cookieParser from 'cookie-parser';
|
|
94
|
+
* import { createExpressAuth } from '@ovixa/auth-client/express';
|
|
95
|
+
* import { OvixaAuth } from '@ovixa/auth-client';
|
|
96
|
+
*
|
|
97
|
+
* const auth = new OvixaAuth({
|
|
98
|
+
* authUrl: process.env.AUTH_URL!,
|
|
99
|
+
* realmId: process.env.AUTH_REALM_ID!,
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* const app = express();
|
|
103
|
+
* app.use(cookieParser());
|
|
104
|
+
* app.use(createExpressAuth({
|
|
105
|
+
* auth,
|
|
106
|
+
* publicRoutes: ['/', '/login', '/signup'],
|
|
107
|
+
* loginRedirect: '/login',
|
|
108
|
+
* cookies: {
|
|
109
|
+
* secure: process.env.NODE_ENV === 'production',
|
|
110
|
+
* },
|
|
111
|
+
* }));
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function createExpressAuth(config: AuthMiddlewareConfig): ExpressMiddleware;
|
|
115
|
+
/**
|
|
116
|
+
* Express middleware to require authentication on specific routes.
|
|
117
|
+
*
|
|
118
|
+
* Use this as an additional guard on routes that must be authenticated,
|
|
119
|
+
* even when the main middleware is configured with `loginRedirect`.
|
|
120
|
+
*
|
|
121
|
+
* @param options - Optional configuration
|
|
122
|
+
* @returns Express middleware
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* import { requireAuth } from '@ovixa/auth-client/express';
|
|
127
|
+
*
|
|
128
|
+
* // API route that requires authentication (returns 401 if not authenticated)
|
|
129
|
+
* app.get('/api/me', requireAuth(), (req, res) => {
|
|
130
|
+
* res.json({ user: req.auth.user });
|
|
131
|
+
* });
|
|
132
|
+
*
|
|
133
|
+
* // API route with custom redirect
|
|
134
|
+
* app.get('/dashboard', requireAuth({ redirect: '/login' }), (req, res) => {
|
|
135
|
+
* res.render('dashboard', { user: req.auth.user });
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
declare function requireAuth(options?: {
|
|
140
|
+
redirect?: string;
|
|
141
|
+
}): ExpressMiddleware;
|
|
142
|
+
/**
|
|
143
|
+
* Set authentication cookies after login.
|
|
144
|
+
*
|
|
145
|
+
* Call this after a successful login to store tokens in cookies.
|
|
146
|
+
*
|
|
147
|
+
* @param res - Express response object
|
|
148
|
+
* @param req - Express request object (for adapter consistency)
|
|
149
|
+
* @param tokens - Token response from login/verify/OAuth callback
|
|
150
|
+
* @param cookieOptions - Optional cookie configuration overrides
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* import { setExpressAuthCookies } from '@ovixa/auth-client/express';
|
|
155
|
+
* import { auth } from './lib/auth';
|
|
156
|
+
*
|
|
157
|
+
* app.post('/api/login', async (req, res) => {
|
|
158
|
+
* const { email, password } = req.body;
|
|
159
|
+
* const tokens = await auth.login({ email, password });
|
|
160
|
+
*
|
|
161
|
+
* setExpressAuthCookies(res, req, tokens);
|
|
162
|
+
*
|
|
163
|
+
* res.json({ success: true });
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
declare function setExpressAuthCookies(res: ExpressResponse, req: ExpressRequest, tokens: TokenResponse, cookieOptions?: CookieOptions): void;
|
|
168
|
+
/**
|
|
169
|
+
* Clear authentication cookies on logout.
|
|
170
|
+
*
|
|
171
|
+
* Call this to log out the user by removing their session cookies.
|
|
172
|
+
*
|
|
173
|
+
* @param res - Express response object
|
|
174
|
+
* @param req - Express request object (for adapter consistency)
|
|
175
|
+
* @param cookieOptions - Optional cookie configuration overrides
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* import { clearExpressAuthCookies } from '@ovixa/auth-client/express';
|
|
180
|
+
* import { auth } from './lib/auth';
|
|
181
|
+
*
|
|
182
|
+
* app.post('/api/logout', async (req, res) => {
|
|
183
|
+
* // Revoke refresh token on server
|
|
184
|
+
* if (req.auth?.session?.refreshToken) {
|
|
185
|
+
* await auth.logout(req.auth.session.refreshToken);
|
|
186
|
+
* }
|
|
187
|
+
*
|
|
188
|
+
* // Clear cookies
|
|
189
|
+
* clearExpressAuthCookies(res, req);
|
|
190
|
+
*
|
|
191
|
+
* res.json({ success: true });
|
|
192
|
+
* });
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
declare function clearExpressAuthCookies(res: ExpressResponse, req: ExpressRequest, cookieOptions?: CookieOptions): void;
|
|
196
|
+
|
|
197
|
+
export { AuthContext, AuthMiddlewareConfig, CookieOptions, clearExpressAuthCookies, createExpressAuth, requireAuth, setExpressAuthCookies };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkAuth,
|
|
3
|
+
clearAuthCookies,
|
|
4
|
+
isPublicRoute,
|
|
5
|
+
setAuthCookies
|
|
6
|
+
} from "../chunk-Y5NJCTZO.js";
|
|
7
|
+
import "../chunk-UHRF6AFJ.js";
|
|
8
|
+
|
|
9
|
+
// src/middleware/express.ts
|
|
10
|
+
var ExpressCookieAdapter = class {
|
|
11
|
+
constructor(req, res) {
|
|
12
|
+
this.req = req;
|
|
13
|
+
this.res = res;
|
|
14
|
+
}
|
|
15
|
+
getCookie(name) {
|
|
16
|
+
return this.req.cookies[name];
|
|
17
|
+
}
|
|
18
|
+
setCookie(name, value, options) {
|
|
19
|
+
this.res.cookie(name, value, {
|
|
20
|
+
path: options.path,
|
|
21
|
+
secure: options.secure,
|
|
22
|
+
httpOnly: options.httpOnly,
|
|
23
|
+
sameSite: options.sameSite,
|
|
24
|
+
domain: options.domain,
|
|
25
|
+
maxAge: options.maxAge ? options.maxAge * 1e3 : void 0,
|
|
26
|
+
// Express uses milliseconds
|
|
27
|
+
expires: options.expires
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
deleteCookie(name, options) {
|
|
31
|
+
this.res.clearCookie(name, {
|
|
32
|
+
path: options.path,
|
|
33
|
+
domain: options.domain
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
function createExpressAuth(config) {
|
|
38
|
+
const { auth, cookies, publicRoutes = [], loginRedirect, autoRefresh = true } = config;
|
|
39
|
+
return async (req, res, next) => {
|
|
40
|
+
const path = req.path;
|
|
41
|
+
const isPublic = isPublicRoute(path, publicRoutes);
|
|
42
|
+
const adapter = new ExpressCookieAdapter(req, res);
|
|
43
|
+
const result = await checkAuth(auth, adapter, cookies, autoRefresh);
|
|
44
|
+
if (result.newTokens) {
|
|
45
|
+
setAuthCookies(adapter, result.newTokens, cookies);
|
|
46
|
+
}
|
|
47
|
+
req.auth = result.context;
|
|
48
|
+
if (result.context.isAuthenticated || isPublic) {
|
|
49
|
+
return next();
|
|
50
|
+
}
|
|
51
|
+
if (loginRedirect) {
|
|
52
|
+
const returnUrl = encodeURIComponent(req.originalUrl);
|
|
53
|
+
const redirectUrl = `${loginRedirect}?returnUrl=${returnUrl}`;
|
|
54
|
+
res.redirect(302, redirectUrl);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function requireAuth(options) {
|
|
61
|
+
return (req, res, next) => {
|
|
62
|
+
if (req.auth?.isAuthenticated) {
|
|
63
|
+
return next();
|
|
64
|
+
}
|
|
65
|
+
if (options?.redirect) {
|
|
66
|
+
const returnUrl = encodeURIComponent(req.originalUrl);
|
|
67
|
+
res.redirect(302, `${options.redirect}?returnUrl=${returnUrl}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function setExpressAuthCookies(res, req, tokens, cookieOptions) {
|
|
74
|
+
const adapter = new ExpressCookieAdapter(req, res);
|
|
75
|
+
setAuthCookies(adapter, tokens, cookieOptions);
|
|
76
|
+
}
|
|
77
|
+
function clearExpressAuthCookies(res, req, cookieOptions) {
|
|
78
|
+
const adapter = new ExpressCookieAdapter(req, res);
|
|
79
|
+
clearAuthCookies(adapter, cookieOptions);
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
clearExpressAuthCookies,
|
|
83
|
+
createExpressAuth,
|
|
84
|
+
requireAuth,
|
|
85
|
+
setExpressAuthCookies
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/middleware/express.ts"],"sourcesContent":["/**\n * Express middleware for @ovixa/auth-client\n *\n * Provides authentication middleware for Express applications using cookie-based sessions.\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import cookieParser from 'cookie-parser';\n * import { createExpressAuth, requireAuth } from '@ovixa/auth-client/express';\n * import { auth } from './lib/auth';\n *\n * const app = express();\n * app.use(cookieParser());\n * app.use(createExpressAuth({\n * auth,\n * publicRoutes: ['/', '/login', '/signup', '/api/public/*'],\n * loginRedirect: '/login',\n * }));\n *\n * // Protected routes\n * app.get('/api/me', requireAuth(), (req, res) => {\n * res.json({ user: req.auth.user });\n * });\n * ```\n */\n\nimport type { TokenResponse } from '../index.js';\nimport type {\n AuthMiddlewareConfig,\n AuthContext,\n CookieAdapter,\n SetCookieOptions,\n DeleteCookieOptions,\n CookieOptions,\n} from './types.js';\nimport { isPublicRoute } from './types.js';\nimport {\n checkAuth,\n setAuthCookies as coreSetAuthCookies,\n clearAuthCookies as coreClearAuthCookies,\n} from './core.js';\n\n/**\n * Express Request type (minimal subset we need).\n * We use this instead of importing from 'express' to avoid requiring it as a dependency.\n */\ninterface ExpressRequest {\n path: string;\n url: string;\n originalUrl: string;\n cookies: Record<string, string>;\n auth?: AuthContext;\n}\n\n/**\n * Express Response type (minimal subset we need).\n */\ninterface ExpressResponse {\n cookie(name: string, value: string, options?: ExpressCookieOptions): this;\n clearCookie(name: string, options?: ExpressClearCookieOptions): this;\n redirect(url: string): void;\n redirect(status: number, url: string): void;\n status(code: number): this;\n json(body: unknown): this;\n}\n\ninterface ExpressCookieOptions {\n path?: string;\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: 'strict' | 'lax' | 'none' | boolean;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n}\n\ninterface ExpressClearCookieOptions {\n path?: string;\n domain?: string;\n}\n\n/**\n * Express next function.\n */\ntype ExpressNextFunction = (err?: unknown) => void;\n\n/**\n * Express middleware handler type.\n */\ntype ExpressMiddleware = (\n req: ExpressRequest,\n res: ExpressResponse,\n next: ExpressNextFunction\n) => void | Promise<void>;\n\n/**\n * Cookie adapter for Express's cookie API.\n *\n * Requires `cookie-parser` middleware to be installed and used before this middleware.\n */\nclass ExpressCookieAdapter implements CookieAdapter {\n constructor(\n private req: ExpressRequest,\n private res: ExpressResponse\n ) {}\n\n getCookie(name: string): string | undefined {\n return this.req.cookies[name];\n }\n\n setCookie(name: string, value: string, options: SetCookieOptions): void {\n this.res.cookie(name, value, {\n path: options.path,\n secure: options.secure,\n httpOnly: options.httpOnly,\n sameSite: options.sameSite,\n domain: options.domain,\n maxAge: options.maxAge ? options.maxAge * 1000 : undefined, // Express uses milliseconds\n expires: options.expires,\n });\n }\n\n deleteCookie(name: string, options: DeleteCookieOptions): void {\n this.res.clearCookie(name, {\n path: options.path,\n domain: options.domain,\n });\n }\n}\n\n/**\n * Create Express authentication middleware.\n *\n * This middleware:\n * - Checks authentication status from cookies on each request\n * - Automatically refreshes expired access tokens using refresh tokens\n * - Sets `req.auth` with the authentication context\n * - Optionally redirects unauthenticated requests to a login page\n * - Allows public routes to bypass authentication\n *\n * **Note:** Requires `cookie-parser` middleware to be installed and used before this middleware.\n *\n * @param config - Middleware configuration\n * @returns Express middleware\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import cookieParser from 'cookie-parser';\n * import { createExpressAuth } from '@ovixa/auth-client/express';\n * import { OvixaAuth } from '@ovixa/auth-client';\n *\n * const auth = new OvixaAuth({\n * authUrl: process.env.AUTH_URL!,\n * realmId: process.env.AUTH_REALM_ID!,\n * });\n *\n * const app = express();\n * app.use(cookieParser());\n * app.use(createExpressAuth({\n * auth,\n * publicRoutes: ['/', '/login', '/signup'],\n * loginRedirect: '/login',\n * cookies: {\n * secure: process.env.NODE_ENV === 'production',\n * },\n * }));\n * ```\n */\nexport function createExpressAuth(config: AuthMiddlewareConfig): ExpressMiddleware {\n const { auth, cookies, publicRoutes = [], loginRedirect, autoRefresh = true } = config;\n\n return async (\n req: ExpressRequest,\n res: ExpressResponse,\n next: ExpressNextFunction\n ): Promise<void> => {\n const path = req.path;\n\n // Check if this is a public route\n const isPublic = isPublicRoute(path, publicRoutes);\n\n // Create cookie adapter\n const adapter = new ExpressCookieAdapter(req, res);\n\n // Check authentication status\n const result = await checkAuth(auth, adapter, cookies, autoRefresh);\n\n // If tokens were refreshed, update cookies\n if (result.newTokens) {\n coreSetAuthCookies(adapter, result.newTokens, cookies);\n }\n\n // Set auth context on request\n req.auth = result.context;\n\n // If authenticated or public route, continue\n if (result.context.isAuthenticated || isPublic) {\n return next();\n }\n\n // Not authenticated and not public - redirect or return 401\n if (loginRedirect) {\n // Add return URL as query param for redirect after login\n const returnUrl = encodeURIComponent(req.originalUrl);\n const redirectUrl = `${loginRedirect}?returnUrl=${returnUrl}`;\n res.redirect(302, redirectUrl);\n return;\n }\n\n // Return 401 Unauthorized\n res.status(401).json({ error: 'Unauthorized' });\n };\n}\n\n/**\n * Express middleware to require authentication on specific routes.\n *\n * Use this as an additional guard on routes that must be authenticated,\n * even when the main middleware is configured with `loginRedirect`.\n *\n * @param options - Optional configuration\n * @returns Express middleware\n *\n * @example\n * ```typescript\n * import { requireAuth } from '@ovixa/auth-client/express';\n *\n * // API route that requires authentication (returns 401 if not authenticated)\n * app.get('/api/me', requireAuth(), (req, res) => {\n * res.json({ user: req.auth.user });\n * });\n *\n * // API route with custom redirect\n * app.get('/dashboard', requireAuth({ redirect: '/login' }), (req, res) => {\n * res.render('dashboard', { user: req.auth.user });\n * });\n * ```\n */\nexport function requireAuth(options?: { redirect?: string }): ExpressMiddleware {\n return (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): void => {\n if (req.auth?.isAuthenticated) {\n return next();\n }\n\n if (options?.redirect) {\n const returnUrl = encodeURIComponent(req.originalUrl);\n res.redirect(302, `${options.redirect}?returnUrl=${returnUrl}`);\n return;\n }\n\n res.status(401).json({ error: 'Unauthorized' });\n };\n}\n\n/**\n * Set authentication cookies after login.\n *\n * Call this after a successful login to store tokens in cookies.\n *\n * @param res - Express response object\n * @param req - Express request object (for adapter consistency)\n * @param tokens - Token response from login/verify/OAuth callback\n * @param cookieOptions - Optional cookie configuration overrides\n *\n * @example\n * ```typescript\n * import { setExpressAuthCookies } from '@ovixa/auth-client/express';\n * import { auth } from './lib/auth';\n *\n * app.post('/api/login', async (req, res) => {\n * const { email, password } = req.body;\n * const tokens = await auth.login({ email, password });\n *\n * setExpressAuthCookies(res, req, tokens);\n *\n * res.json({ success: true });\n * });\n * ```\n */\nexport function setExpressAuthCookies(\n res: ExpressResponse,\n req: ExpressRequest,\n tokens: TokenResponse,\n cookieOptions?: CookieOptions\n): void {\n const adapter = new ExpressCookieAdapter(req, res);\n coreSetAuthCookies(adapter, tokens, cookieOptions);\n}\n\n/**\n * Clear authentication cookies on logout.\n *\n * Call this to log out the user by removing their session cookies.\n *\n * @param res - Express response object\n * @param req - Express request object (for adapter consistency)\n * @param cookieOptions - Optional cookie configuration overrides\n *\n * @example\n * ```typescript\n * import { clearExpressAuthCookies } from '@ovixa/auth-client/express';\n * import { auth } from './lib/auth';\n *\n * app.post('/api/logout', async (req, res) => {\n * // Revoke refresh token on server\n * if (req.auth?.session?.refreshToken) {\n * await auth.logout(req.auth.session.refreshToken);\n * }\n *\n * // Clear cookies\n * clearExpressAuthCookies(res, req);\n *\n * res.json({ success: true });\n * });\n * ```\n */\nexport function clearExpressAuthCookies(\n res: ExpressResponse,\n req: ExpressRequest,\n cookieOptions?: CookieOptions\n): void {\n const adapter = new ExpressCookieAdapter(req, res);\n coreClearAuthCookies(adapter, cookieOptions);\n}\n\n// Re-export types for convenience\nexport type { AuthMiddlewareConfig, AuthContext, CookieOptions } from './types.js';\n"],"mappings":";;;;;;;;;AAqGA,IAAM,uBAAN,MAAoD;AAAA,EAClD,YACU,KACA,KACR;AAFQ;AACA;AAAA,EACP;AAAA,EAEH,UAAU,MAAkC;AAC1C,WAAO,KAAK,IAAI,QAAQ,IAAI;AAAA,EAC9B;AAAA,EAEA,UAAU,MAAc,OAAe,SAAiC;AACtE,SAAK,IAAI,OAAO,MAAM,OAAO;AAAA,MAC3B,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ,SAAS,QAAQ,SAAS,MAAO;AAAA;AAAA,MACjD,SAAS,QAAQ;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,MAAc,SAAoC;AAC7D,SAAK,IAAI,YAAY,MAAM;AAAA,MACzB,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AACF;AAyCO,SAAS,kBAAkB,QAAiD;AACjF,QAAM,EAAE,MAAM,SAAS,eAAe,CAAC,GAAG,eAAe,cAAc,KAAK,IAAI;AAEhF,SAAO,OACL,KACA,KACA,SACkB;AAClB,UAAM,OAAO,IAAI;AAGjB,UAAM,WAAW,cAAc,MAAM,YAAY;AAGjD,UAAM,UAAU,IAAI,qBAAqB,KAAK,GAAG;AAGjD,UAAM,SAAS,MAAM,UAAU,MAAM,SAAS,SAAS,WAAW;AAGlE,QAAI,OAAO,WAAW;AACpB,qBAAmB,SAAS,OAAO,WAAW,OAAO;AAAA,IACvD;AAGA,QAAI,OAAO,OAAO;AAGlB,QAAI,OAAO,QAAQ,mBAAmB,UAAU;AAC9C,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,eAAe;AAEjB,YAAM,YAAY,mBAAmB,IAAI,WAAW;AACpD,YAAM,cAAc,GAAG,aAAa,cAAc,SAAS;AAC3D,UAAI,SAAS,KAAK,WAAW;AAC7B;AAAA,IACF;AAGA,QAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,eAAe,CAAC;AAAA,EAChD;AACF;AA0BO,SAAS,YAAY,SAAoD;AAC9E,SAAO,CAAC,KAAqB,KAAsB,SAAoC;AACrF,QAAI,IAAI,MAAM,iBAAiB;AAC7B,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,SAAS,UAAU;AACrB,YAAM,YAAY,mBAAmB,IAAI,WAAW;AACpD,UAAI,SAAS,KAAK,GAAG,QAAQ,QAAQ,cAAc,SAAS,EAAE;AAC9D;AAAA,IACF;AAEA,QAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,eAAe,CAAC;AAAA,EAChD;AACF;AA2BO,SAAS,sBACd,KACA,KACA,QACA,eACM;AACN,QAAM,UAAU,IAAI,qBAAqB,KAAK,GAAG;AACjD,iBAAmB,SAAS,QAAQ,aAAa;AACnD;AA6BO,SAAS,wBACd,KACA,KACA,eACM;AACN,QAAM,UAAU,IAAI,qBAAqB,KAAK,GAAG;AACjD,mBAAqB,SAAS,aAAa;AAC7C;","names":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { OvixaAuth, User, Session } from './index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Middleware types for @ovixa/auth-client
|
|
5
|
+
*
|
|
6
|
+
* Provides generic adapter interfaces and shared types for framework integrations.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Cookie configuration options for auth middleware.
|
|
11
|
+
*/
|
|
12
|
+
interface CookieOptions {
|
|
13
|
+
/** Name of the access token cookie (default: 'ovixa_access_token') */
|
|
14
|
+
accessTokenCookie?: string;
|
|
15
|
+
/** Name of the refresh token cookie (default: 'ovixa_refresh_token') */
|
|
16
|
+
refreshTokenCookie?: string;
|
|
17
|
+
/** Cookie path (default: '/') */
|
|
18
|
+
path?: string;
|
|
19
|
+
/** Whether to use secure cookies (default: true) */
|
|
20
|
+
secure?: boolean;
|
|
21
|
+
/** Whether cookies are HTTP-only (default: true) */
|
|
22
|
+
httpOnly?: boolean;
|
|
23
|
+
/** SameSite cookie policy (default: 'lax') */
|
|
24
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
25
|
+
/** Cookie domain (optional, defaults to current domain) */
|
|
26
|
+
domain?: string;
|
|
27
|
+
/** Max age for cookies in seconds (optional, defaults to token expiry) */
|
|
28
|
+
maxAge?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for auth middleware.
|
|
32
|
+
*/
|
|
33
|
+
interface AuthMiddlewareConfig {
|
|
34
|
+
/** OvixaAuth client instance */
|
|
35
|
+
auth: OvixaAuth;
|
|
36
|
+
/** Cookie configuration options */
|
|
37
|
+
cookies?: CookieOptions;
|
|
38
|
+
/** Routes that don't require authentication */
|
|
39
|
+
publicRoutes?: string[];
|
|
40
|
+
/** URL to redirect unauthenticated requests (if not set, returns 401) */
|
|
41
|
+
loginRedirect?: string;
|
|
42
|
+
/** Whether to automatically refresh expired tokens (default: true) */
|
|
43
|
+
autoRefresh?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Authentication context available in request handlers.
|
|
47
|
+
*/
|
|
48
|
+
interface AuthContext {
|
|
49
|
+
/** The authenticated user, or null if not authenticated */
|
|
50
|
+
user: User | null;
|
|
51
|
+
/** The current session, or null if not authenticated */
|
|
52
|
+
session: Session | null;
|
|
53
|
+
/** Whether the request is authenticated */
|
|
54
|
+
isAuthenticated: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type { AuthMiddlewareConfig as A, CookieOptions as C, AuthContext as a };
|