@gneiss/client-auth 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +73 -55
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/esm/index.mjs +73 -55
- package/dist/esm/index.mjs.map +2 -2
- package/dist/types/src/frameworks/express/middleware/ExpressAuthGneissClient.d.ts +8 -5
- package/dist/types/src/frameworks/express/middleware/ExpressAuthGneissClient.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -44,7 +44,7 @@ var import_axios2 = require("axios");
|
|
|
44
44
|
// src/config.ts
|
|
45
45
|
var config = {
|
|
46
46
|
authUrl: process.env.ENV === "prod" ? "https://auth.gneiss.io" : process.env.ENV === "staging" ? "https://auth.gneiss.io/testing" : "http://localhost:5000",
|
|
47
|
-
internalAuthUrl: process.env.ENV === "prod" ? "http://auth:
|
|
47
|
+
internalAuthUrl: process.env.ENV === "prod" ? "http://auth:5000" : process.env.ENV === "staging" ? "http://auth:5000/testing" : "http://auth:5000"
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
// src/core/AuthGneissCore.ts
|
|
@@ -315,10 +315,13 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
315
315
|
}
|
|
316
316
|
} catch (error) {
|
|
317
317
|
if (error instanceof import_axios3.AxiosError) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
switch (error.response?.status) {
|
|
319
|
+
default:
|
|
320
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
321
323
|
}
|
|
324
|
+
res.status(500).send("Internal server error");
|
|
322
325
|
}
|
|
323
326
|
}
|
|
324
327
|
/**
|
|
@@ -327,23 +330,25 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
327
330
|
* @param res - The response object.
|
|
328
331
|
* @param next - The next middleware function.
|
|
329
332
|
*/
|
|
330
|
-
async getUser(req, res) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
333
|
+
async getUser(req, res, next) {
|
|
334
|
+
await this.requireAuth(req, res, async () => {
|
|
335
|
+
const cookies = parseCookies(req);
|
|
336
|
+
const accessToken = cookies?.accessToken;
|
|
337
|
+
try {
|
|
338
|
+
const userData = await this.getUserData(accessToken);
|
|
339
|
+
res.status(200).send(userData);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
if (error instanceof import_axios3.AxiosError) {
|
|
342
|
+
switch (error.response?.status) {
|
|
343
|
+
default:
|
|
344
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
342
347
|
}
|
|
348
|
+
console.error("Error in getUser utility function:", error);
|
|
349
|
+
res.status(500).send("Internal server error");
|
|
343
350
|
}
|
|
344
|
-
|
|
345
|
-
res.status(500).send("Internal server error");
|
|
346
|
-
}
|
|
351
|
+
});
|
|
347
352
|
}
|
|
348
353
|
/**
|
|
349
354
|
* handleCallBack is a middleware function that handles the callback from the authentication service.
|
|
@@ -371,12 +376,15 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
371
376
|
}
|
|
372
377
|
} catch (error) {
|
|
373
378
|
if (error instanceof import_axios3.AxiosError) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
+
switch (error.response?.status) {
|
|
380
|
+
default:
|
|
381
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
382
|
+
console.error("DEBUG: error", error);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
379
385
|
}
|
|
386
|
+
res.status(500).send("Internal server error");
|
|
387
|
+
console.error("DEBUG: error", error);
|
|
380
388
|
}
|
|
381
389
|
}
|
|
382
390
|
/**
|
|
@@ -405,50 +413,60 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
405
413
|
}
|
|
406
414
|
/**
|
|
407
415
|
* logoutUser is a function that redirects the user to the Gneiss logout service.
|
|
416
|
+
* It uses requireAuth to ensure the access token is valid before logout.
|
|
408
417
|
* @param req - The request object.
|
|
409
418
|
* @param res - The response object.
|
|
419
|
+
* @param next - The next middleware function.
|
|
410
420
|
*/
|
|
411
|
-
logoutUser(req, res) {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
421
|
+
async logoutUser(req, res, next) {
|
|
422
|
+
await this.requireAuth(req, res, async () => {
|
|
423
|
+
const cookies = parseCookies(req);
|
|
424
|
+
try {
|
|
425
|
+
await this.logout(cookies?.accessToken);
|
|
426
|
+
clearCookies(res);
|
|
427
|
+
res.redirect("/");
|
|
428
|
+
} catch (error) {
|
|
429
|
+
if (error instanceof import_axios3.AxiosError) {
|
|
430
|
+
switch (error.response?.status) {
|
|
431
|
+
default:
|
|
432
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
422
435
|
}
|
|
436
|
+
console.error("Error in logout middleware:", error);
|
|
437
|
+
res.status(500).send("Internal server error");
|
|
423
438
|
}
|
|
424
|
-
|
|
425
|
-
res.status(500).send("Internal server error");
|
|
426
|
-
}
|
|
439
|
+
});
|
|
427
440
|
}
|
|
428
441
|
/**
|
|
429
|
-
* Utility route handler for deleting a user
|
|
430
|
-
* This ensures that the user is fully logged out before
|
|
431
|
-
* deleting the user's data
|
|
442
|
+
* Utility route handler for deleting a user.
|
|
443
|
+
* This ensures that the user is fully logged out before
|
|
444
|
+
* deleting the user's data.
|
|
432
445
|
*
|
|
433
446
|
* @param req - The request object.
|
|
434
447
|
* @param res - The response object.
|
|
448
|
+
* @param next - The next middleware function.
|
|
435
449
|
*/
|
|
436
|
-
deleteUser(req, res) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
450
|
+
async deleteUser(req, res, next) {
|
|
451
|
+
await this.requireAuth(req, res, async () => {
|
|
452
|
+
const cookies = parseCookies(req);
|
|
453
|
+
try {
|
|
454
|
+
await this.logout(cookies?.accessToken);
|
|
455
|
+
clearCookies(res);
|
|
456
|
+
await this.deleteUserData(cookies?.accessToken);
|
|
457
|
+
res.redirect("/");
|
|
458
|
+
} catch (error) {
|
|
459
|
+
if (error instanceof import_axios3.AxiosError) {
|
|
460
|
+
switch (error.response?.status) {
|
|
461
|
+
default:
|
|
462
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
447
465
|
}
|
|
466
|
+
console.error("Error in deleteUser utility function:", error);
|
|
467
|
+
res.status(500).send("Internal server error");
|
|
448
468
|
}
|
|
449
|
-
|
|
450
|
-
res.status(500).send("Internal server error");
|
|
451
|
-
}
|
|
469
|
+
});
|
|
452
470
|
}
|
|
453
471
|
};
|
|
454
472
|
var ExpressAuthGneissClient_default = ExpressAuthGneissClient;
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts", "../../src/core/AuthGneissCore.ts", "../../src/config.ts", "../../src/utils/storage/cookieHandling.ts", "../../src/frameworks/express/middleware/ExpressAuthGneissClient.ts"],
|
|
4
|
-
"sourcesContent": ["export { ExpressAuthGneissClient } from \"./frameworks\";\nexport { AuthGneissCore } from \"./core\";\nexport { parseCookies } from \"@utils\"\nexport type { AuthGneissCoreConfig, AuthenticatedRequest } from \"./core\";\n\n", "import { AuthGneissCoreConfig } from \"@core/types\";\nimport axios, { AxiosResponse } from \"axios\";\nimport { Tokens } from \"@core/types\";\nimport dotenv from \"dotenv\";\nimport { AxiosError } from \"axios\";\nimport { config as genConfig } from \"@/config\";\nimport { AuthGneissGeneralConfig } from \"@/config\";\n\n//load environment variables if not already set\nif (!process.env.ENV) {\n dotenv.config();\n}\n\n/**\n * AuthGneissCore provides core functionality for OAuth2 authentication flow with Gneiss authentication service.\n * It handles token exchange, token refresh, user data fetching, and token validation.\n * \n * This class serves as a base class that can be extended by framework-specific implementations\n * to provide authentication middleware and handlers.\n */\nclass AuthGneissCore {\n protected config: AuthGneissCoreConfig & AuthGneissGeneralConfig; // Configuration object\n protected authUrl : string;\n protected loginUrl : string;\n protected logoutUrl : string;\n protected signupUrl : string;\n protected callbackUrl : string;\n protected internalAuthUrl : string;\n\n constructor(\n devConfig: AuthGneissCoreConfig,\n generalConfig: AuthGneissGeneralConfig = genConfig\n ) {\n\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.internalAuthUrl = this.config.internalAuthUrl;\n this.loginUrl = `${this.authUrl}/auth/login` // Login URL\n this.logoutUrl = `${this.internalAuthUrl}/auth/logout` // Logout URL\n this.signupUrl = `${this.authUrl}/auth/register` // Signup/register URL\n this.callbackUrl = `${this.config.baseClientUrl}${this.config.callbackRoute}`\n\n //check if environment variables are set\n let errorMsgs = [];\n if (!process.env.ENV) {\n errorMsgs.push(\"ENV is not set in environment variables\");\n }\n if (errorMsgs.length > 0) {\n throw new Error(errorMsgs.join(\"\\n\"));\n }\n }\n\n public getBase64EncodedCallbackUrl(): string {\n return Buffer.from(this.callbackUrl).toString('base64')\n }\n\n /**\n * getTokens is a method that exchanges an authentication code for access and refresh tokens.\n * The client id and secret are passed as basic auth headers to authenticate the client itself.\n * @param authCode - The authentication code received from the Gneiss authentication service.\n * @returns A promise that resolves to an object containing the access and refresh tokens.\n */\n protected async getTokens(authCode : string) : Promise<Tokens> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/access_token?auth_code=${authCode}`;\n //Encode in base64 before transport\n const encodedClientId = btoa(this.config.clientId);\n const encodedClientSecret = btoa(this.config.clientSecret);\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Basic ${encodedClientId}:${encodedClientSecret}`\n }\n });\n return {\n accessToken: response.data.access_token,\n refreshToken: response.data.refresh_token,\n tokenType: response.data.token_type\n } as Tokens;\n } catch (error) {\n // console.error(\"Error in getTokens:\", error);\n throw error;\n }\n }\n \n /**\n * refreshToken is a method that refreshes the access token using the refresh token.\n * @param refreshToken - The refresh token to be used for token refresh.\n * @returns A promise that resolves to the refreshed access token.\n */\n protected async refreshToken(refreshToken: string): Promise<string | null> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/refresh`;\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Bearer ${refreshToken}`\n }\n });\n return response.data.access_token as string;\n } catch (error) {\n // console.error(\"Error in refreshToken:\", error);\n return null;\n }\n }\n\n protected async logout(accessToken : string) {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n await axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n }\n \n /**\n * getUserData is a method that fetches user data using the access token.\n * @param accessToken - The access token to be used for user data fetching.\n * @returns A promise that resolves to the user data.\n */\n public async getUserData(accessToken: string) {\n const url : string = `${this.internalAuthUrl}/resource/user_data`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n if (response.status === 200) {\n return response.data;\n }\n throw new Error(\"Failed to fetch user data\");\n }\n \n /**\n * validateToken is a method that validates the access token.\n * @param token - The access token to be validated.\n * @returns A promise that resolves to a boolean indicating the validity of the token.\n */\n protected async validateToken(token: string): Promise<boolean> {\n try {\n console.log(\"DEBUG: token\", token);\n // Token validation logic\n if (!token) {\n return false;\n }\n const url : string = `${this.internalAuthUrl}/auth/validate_token`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${token}`\n }\n });\n return response.status === 200;\n } catch (error) {\n // console.error(\"Error in validateToken:\", error);\n if (error instanceof AxiosError && error.response?.status === 401) {\n return false;\n } else {\n throw error;\n }\n }\n }\n\n /**\n * getLoginUrl is a method that returns the login URL.\n * @returns The login URL.\n */\n public getLoginUrl() : string | undefined {\n return this.loginUrl;\n }\n\n /**\n * Returns the base auth URL.\n * @returns The base auth URL.\n */\n public getAuthUrl(): string | undefined {\n return this.authUrl;\n }\n\n /**\n * Returns the logout URL.\n * @returns The logout URL.\n */\n public getLogoutUrl(): string | undefined {\n return this.logoutUrl;\n }\n\n /**\n * Returns the signup URL.\n * @returns The signup URL.\n */\n public getSignupUrl(): string | undefined {\n return this.signupUrl;\n }\n\n /**\n * deleteUser deletes the user\n * */\n protected async deleteUserData(accessToken : string) : Promise<object> {\n const response : AxiosResponse = await axios.post(`${this.internalAuthUrl}/resource/delete_user`, {}, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n } \n });\n return response.data;\n }\n}\n\nexport default AuthGneissCore;\n", "export type AuthGneissGeneralConfig = {\n authUrl: string // used by the browser\n internalAuthUrl: string // used internally within the same docker network\n}\n\nexport const config : AuthGneissGeneralConfig = {\n authUrl: process.env.ENV === \"prod\" ? \"https://auth.gneiss.io\" : \n process.env.ENV === \"staging\" ? \"https://auth.gneiss.io/testing\" : \"http://localhost:5000\",\n internalAuthUrl: process.env.ENV === \"prod\" ? \"http://auth:45443\" : \n process.env.ENV === \"staging\" ? \"http://auth:44443/testing\" : \"http://auth:5000\"\n}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\n\n// Helper to determine if we're in production\nconst isProduction = process.env.ENV === 'prod' || process.env.ENV === 'staging';\n\n// Cookie configuration\n// Note: SameSite=None requires Secure=true (HTTPS)\n// In dev, use SameSite=Lax with Angular proxy to avoid cross-origin issues\nconst cookieConfig = {\n httpOnly: true,\n secure: isProduction, // Only secure in production (HTTPS)\n sameSite: 'lax' as const, // Lax works for same-origin (Angular proxy in dev, Nginx in prod)\n};\n\n/**\n * Set the access token in the response cookies.\n * @param res - The response object.\n * @param accessToken - The access token to set.\n */\nfunction setAccessToken(res: Response, accessToken: string) {\n\n const decodedToken = decode(accessToken) as JwtPayload;\n \n // decoded.exp is in seconds since epoch\n // Date.now() returns milliseconds since epoch\n // maxAge needs milliseconds remaining\n if (!decodedToken.exp) {\n throw new Error(\"Access token does not contain an expiration time\");\n }\n \n res.cookie('accessToken', accessToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\n/**\n * Set the refresh token in the response cookies.\n * @param res - The response object.\n * @param refreshToken - The refresh token to set.\n */\nfunction setRefreshToken(res: Response, refreshToken: string) {\n\n const decodedToken = decode(refreshToken) as JwtPayload;\n\n if (!decodedToken.exp) {\n throw new Error(\"Refresh token does not contain an expiration time\");\n }\n\n res.cookie('refreshToken', refreshToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\nfunction parseCookies(req: Request) : { [key: string]: string } {\n const cookies = req.headers.cookie;\n if (!cookies) {\n return {};\n }\n return cookies.split(';').reduce((acc: { [key: string]: string }, cookie) => {\n const [key, value] = cookie.split('=').map(s => s.trim());\n acc[key] = value;\n return acc;\n }, {});\n}\n\n/**\n * Set the state token in the response cookies.\n * @param res - The response object.\n * @param stateToken - The state token to set.\n */\nfunction setUrlToken(res: Response, stateToken: string, exp: number) {\n\n\n res.cookie('urlToken', stateToken, {\n ...cookieConfig,\n maxAge: exp\n });\n}\n\nfunction clearCookies(res: Response) {\n const clearConfig = {\n ...cookieConfig,\n path: '/'\n };\n \n res.clearCookie(\"accessToken\", clearConfig);\n res.clearCookie(\"refreshToken\", clearConfig);\n res.clearCookie(\"urlToken\", clearConfig);\n}\n\nexport { setAccessToken, setRefreshToken, parseCookies, clearCookies, setUrlToken};\n", "import { AuthGneissCore, AuthGneissCoreConfig } from \"@core\";\nimport { Request, Response, NextFunction } from \"express\";\nimport { AuthenticatedRequest, Tokens } from \"@core/types\";\nimport { setAccessToken, setRefreshToken, parseCookies, setUrlToken} from \"@utils\";\nimport { AxiosError } from \"axios\";\nimport axios from \"axios\";\nimport { clearCookies } from \"@/utils/storage/cookieHandling\";\n\n\n/**\n * ExpressAuthGneissClient extends AuthGneissCore to provide Express-specific authentication middleware\n * and functionality for handling OAuth2 authentication flow with Gneiss authentication service.\n * \n * @extends AuthGneissCore\n * @example\n * const authClient = new ExpressAuthGneissClient({\n * clientId: 'your-client-id',\n * clientSecret: 'your-client-secret',\n * redirectUrl: 'your-redirect-url'\n * });\n */\nclass ExpressAuthGneissClient extends AuthGneissCore {\n\n private returnUrlStore = new Map<string, string>();\n private readonly URL_STORE_TTL = 10 * 60 * 1000; // 10 minutes\n\n constructor(\n config: AuthGneissCoreConfig\n ) {\n super(config);\n \n // Bind the methods in constructor\n this.requireAuth = this.requireAuth.bind(this);\n this.handleCallBack = this.handleCallBack.bind(this);\n this.loginUser = this.loginUser.bind(this);\n this.logoutUser = this.logoutUser.bind(this);\n this.getUser = this.getUser.bind(this);\n this.deleteUser = this.deleteUser.bind(this);\n this.getUserData = this.getUserData.bind(this);\n this.getLoginUrl = this.getLoginUrl.bind(this);\n this.getLogoutUrl = this.getLogoutUrl.bind(this);\n this.getSignupUrl = this.getSignupUrl.bind(this);\n this.getAuthUrl = this.getAuthUrl.bind(this);\n }\n\n /**\n /**\n * requireAuth is a middleware function that checks if the access token is valid.\n * If the access token is not valid, it attempts to refresh the token using the refresh token.\n * If the refresh token is not valid, it redirects the user to the login page.\n * @template UserT - The type of the user object to attach to the request.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async requireAuth<UserT>(req: Request, res: Response, next: NextFunction): Promise<void> {\n const cookies = parseCookies(req);\n //Check for the existence of the access token\n // console.log(\"DEBUG: cookies\", cookies);\n try {\n const isAccessTokenValid : boolean = await this.validateToken(cookies?.accessToken);\n if (!isAccessTokenValid) { //if the access token is not valid\n //try to refresh the token\n const newAccessToken : string | null = await this.refreshToken(cookies?.refreshToken);\n if (newAccessToken) { // set access token and then call next to proceed to the next middleware/handler\n setAccessToken(res, newAccessToken);\n next()\n }\n else {\n // no access token or valid refresh token, redirect to login with 401 requires login credentials\n res.redirect(401, `${this.loginUrl}?redirect_url=${this.getBase64EncodedCallbackUrl()}`);\n }\n }\n else {\n // access token is valid, continue to the next middleware or route handler after adding user to req\n (req as AuthenticatedRequest<UserT>).user = await this.getUserData(cookies.accessToken);\n next();\n }\n } catch (error) {\n // console.error('Error in requireAuth middleware:', error);\n if (error instanceof AxiosError) {\n res.status((error as AxiosError).response?.status || 500).send((error as AxiosError).response?.data || 'Internal server error');\n } else {\n res.status(500).send('Internal server error');\n }\n }\n }\n\n /**\n * getUserData is a middleware function that fetches user data using the access token.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async getUser(req: Request, res: Response): Promise<void> {\n const cookies = parseCookies(req);\n const accessToken = cookies?.accessToken;\n try {\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n case 401:\n res.redirect(401, this.loginUrl);\n return;\n }\n }\n console.error('Error in getUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * handleCallBack is a middleware function that handles the callback from the authentication service.\n * It extracts the auth code from the request URL parameters, exchanges it for tokens, and sets the access and refresh tokens in the response cookies.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async handleCallBack(\n req: Request,\n res: Response,\n next: NextFunction\n ): Promise<void> {\n\n const cookies = parseCookies(req);\n const returnToToken = cookies?.urlToken\n\n try {\n const authCode: string | undefined = req.query.auth_code as string;\n const returnToUrl = this.returnUrlStore.get(returnToToken);\n\n if (!authCode) {\n throw new Error(\"No auth code found in request url parameters\");\n }\n\n const tokens: Tokens = await this.getTokens(authCode);\n \n // Set the access and refresh tokens in the response cookies\n setAccessToken(res, tokens.accessToken);\n setRefreshToken(res, tokens.refreshToken);\n\n if (returnToUrl) {\n // Go to the original request url\n res.redirect(returnToUrl);\n }\n else {\n // Go to the root url\n res.redirect(\"/\")\n }\n } catch (error) {\n // console.error('Error in handleCallBack middleware:', error);\n if (error instanceof AxiosError) {\n res.status((error as AxiosError).response?.status || 500).send((error as AxiosError).response?.data || 'Internal server error');\n console.error(\"DEBUG: error\", error);\n } else {\n res.status(500).send('Internal server error');\n console.error(\"DEBUG: error\", error);\n }\n }\n }\n\n /**\n * login is a function that redirects the user to the Gneiss authentication service for authentication.\n * Accepts an optional returnTo query parameter to specify where to redirect after successful login.\n * Falls back to referer header if no returnTo is provided.\n * @param req - The request object.\n * @param res - The response object.\n */\n public loginUser(req: Request, res: Response): void {\n try {\n if (!this.loginUrl) {\n throw new Error('Login URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n\n // Priority: query param > referer header > environment variable\n // In dev with proxy, referer will be the frontend URL (e.g., http://localhost:4200)\n // In staging, FRONTEND_URL should be set to staging frontend URL\n const returnToUrl = \n (req.query.returnTo as string) || \n req.get('referer') || \n process.env.FRONTEND_URL || \n '/'; // Fallback to root path (same origin)\n \n const urlToken = crypto.randomUUID();\n\n // Store the returnToUrl with auto-expiration\n this.returnUrlStore.set(urlToken, returnToUrl);\n setUrlToken(res, urlToken, this.URL_STORE_TTL);\n setTimeout(() => this.returnUrlStore.delete(urlToken), this.URL_STORE_TTL);\n\n //Base64 encode callback url\n const callbackUrl = this.getBase64EncodedCallbackUrl();\n\n res.redirect(this.loginUrl + `?redirect_url=${callbackUrl}`);\n } catch (error) {\n console.error('Error in login middleware:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * logoutUser is a function that redirects the user to the Gneiss logout service.\n * @param req - The request object.\n * @param res - The response object.\n */\n public logoutUser(req: Request, res: Response): void {\n const cookies = parseCookies(req);\n try {\n this.logout(cookies?.accessToken)\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\") // Redirect back to home after logout\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n case 401:\n res.redirect(401, this.loginUrl)\n }\n }\n console.error('Error in logout middleware:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * Utility route handler for deleting a user\n * This ensures that the user is fully logged out before \n * deleting the user's data\n * \n * @param req - The request object.\n * @param res - The response object.\n */\n public deleteUser(req: Request, res: Response) {\n const cookies = parseCookies(req);\n try {\n this.logoutUser(req, res);\n this.deleteUserData(cookies?.accessToken);\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n case 401:\n res.redirect(401, this.loginUrl);\n return;\n }\n }\n console.error('Error in deleteUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,mBAAqC;AAErC,oBAAmB;AACnB,IAAAA,gBAA2B;;;ACCpB,IAAM,SAAmC;AAAA,EAC5C,SAAS,QAAQ,IAAI,QAAQ,SAAS,2BACtC,QAAQ,IAAI,QAAQ,YAAY,mCAAmC;AAAA,EACnE,iBAAiB,QAAQ,IAAI,QAAQ,SAAS,
|
|
4
|
+
"sourcesContent": ["export { ExpressAuthGneissClient } from \"./frameworks\";\nexport { AuthGneissCore } from \"./core\";\nexport { parseCookies } from \"@utils\"\nexport type { AuthGneissCoreConfig, AuthenticatedRequest } from \"./core\";\n\n", "import { AuthGneissCoreConfig } from \"@core/types\";\nimport axios, { AxiosResponse } from \"axios\";\nimport { Tokens } from \"@core/types\";\nimport dotenv from \"dotenv\";\nimport { AxiosError } from \"axios\";\nimport { config as genConfig } from \"@/config\";\nimport { AuthGneissGeneralConfig } from \"@/config\";\n\n//load environment variables if not already set\nif (!process.env.ENV) {\n dotenv.config();\n}\n\n/**\n * AuthGneissCore provides core functionality for OAuth2 authentication flow with Gneiss authentication service.\n * It handles token exchange, token refresh, user data fetching, and token validation.\n * \n * This class serves as a base class that can be extended by framework-specific implementations\n * to provide authentication middleware and handlers.\n */\nclass AuthGneissCore {\n protected config: AuthGneissCoreConfig & AuthGneissGeneralConfig; // Configuration object\n protected authUrl : string;\n protected loginUrl : string;\n protected logoutUrl : string;\n protected signupUrl : string;\n protected callbackUrl : string;\n protected internalAuthUrl : string;\n\n constructor(\n devConfig: AuthGneissCoreConfig,\n generalConfig: AuthGneissGeneralConfig = genConfig\n ) {\n\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.internalAuthUrl = this.config.internalAuthUrl;\n this.loginUrl = `${this.authUrl}/auth/login` // Login URL\n this.logoutUrl = `${this.internalAuthUrl}/auth/logout` // Logout URL\n this.signupUrl = `${this.authUrl}/auth/register` // Signup/register URL\n this.callbackUrl = `${this.config.baseClientUrl}${this.config.callbackRoute}`\n\n //check if environment variables are set\n let errorMsgs = [];\n if (!process.env.ENV) {\n errorMsgs.push(\"ENV is not set in environment variables\");\n }\n if (errorMsgs.length > 0) {\n throw new Error(errorMsgs.join(\"\\n\"));\n }\n }\n\n public getBase64EncodedCallbackUrl(): string {\n return Buffer.from(this.callbackUrl).toString('base64')\n }\n\n /**\n * getTokens is a method that exchanges an authentication code for access and refresh tokens.\n * The client id and secret are passed as basic auth headers to authenticate the client itself.\n * @param authCode - The authentication code received from the Gneiss authentication service.\n * @returns A promise that resolves to an object containing the access and refresh tokens.\n */\n protected async getTokens(authCode : string) : Promise<Tokens> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/access_token?auth_code=${authCode}`;\n //Encode in base64 before transport\n const encodedClientId = btoa(this.config.clientId);\n const encodedClientSecret = btoa(this.config.clientSecret);\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Basic ${encodedClientId}:${encodedClientSecret}`\n }\n });\n return {\n accessToken: response.data.access_token,\n refreshToken: response.data.refresh_token,\n tokenType: response.data.token_type\n } as Tokens;\n } catch (error) {\n // console.error(\"Error in getTokens:\", error);\n throw error;\n }\n }\n \n /**\n * refreshToken is a method that refreshes the access token using the refresh token.\n * @param refreshToken - The refresh token to be used for token refresh.\n * @returns A promise that resolves to the refreshed access token.\n */\n protected async refreshToken(refreshToken: string): Promise<string | null> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/refresh`;\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Bearer ${refreshToken}`\n }\n });\n return response.data.access_token as string;\n } catch (error) {\n // console.error(\"Error in refreshToken:\", error);\n return null;\n }\n }\n\n protected async logout(accessToken : string) {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n await axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n }\n \n /**\n * getUserData is a method that fetches user data using the access token.\n * @param accessToken - The access token to be used for user data fetching.\n * @returns A promise that resolves to the user data.\n */\n public async getUserData(accessToken: string) {\n const url : string = `${this.internalAuthUrl}/resource/user_data`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n if (response.status === 200) {\n return response.data;\n }\n throw new Error(\"Failed to fetch user data\");\n }\n \n /**\n * validateToken is a method that validates the access token.\n * @param token - The access token to be validated.\n * @returns A promise that resolves to a boolean indicating the validity of the token.\n */\n protected async validateToken(token: string): Promise<boolean> {\n try {\n console.log(\"DEBUG: token\", token);\n // Token validation logic\n if (!token) {\n return false;\n }\n const url : string = `${this.internalAuthUrl}/auth/validate_token`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${token}`\n }\n });\n return response.status === 200;\n } catch (error) {\n // console.error(\"Error in validateToken:\", error);\n if (error instanceof AxiosError && error.response?.status === 401) {\n return false;\n } else {\n throw error;\n }\n }\n }\n\n /**\n * getLoginUrl is a method that returns the login URL.\n * @returns The login URL.\n */\n public getLoginUrl() : string | undefined {\n return this.loginUrl;\n }\n\n /**\n * Returns the base auth URL.\n * @returns The base auth URL.\n */\n public getAuthUrl(): string | undefined {\n return this.authUrl;\n }\n\n /**\n * Returns the logout URL.\n * @returns The logout URL.\n */\n public getLogoutUrl(): string | undefined {\n return this.logoutUrl;\n }\n\n /**\n * Returns the signup URL.\n * @returns The signup URL.\n */\n public getSignupUrl(): string | undefined {\n return this.signupUrl;\n }\n\n /**\n * deleteUser deletes the user\n * */\n protected async deleteUserData(accessToken : string) : Promise<object> {\n const response : AxiosResponse = await axios.post(`${this.internalAuthUrl}/resource/delete_user`, {}, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n } \n });\n return response.data;\n }\n}\n\nexport default AuthGneissCore;\n", "export type AuthGneissGeneralConfig = {\n authUrl: string // used by the browser\n internalAuthUrl: string // used internally within the same docker network\n}\n\nexport const config : AuthGneissGeneralConfig = {\n authUrl: process.env.ENV === \"prod\" ? \"https://auth.gneiss.io\" : \n process.env.ENV === \"staging\" ? \"https://auth.gneiss.io/testing\" : \"http://localhost:5000\",\n internalAuthUrl: process.env.ENV === \"prod\" ? \"http://auth:5000\" : \n process.env.ENV === \"staging\" ? \"http://auth:5000/testing\" : \"http://auth:5000\"\n}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\n\n// Helper to determine if we're in production\nconst isProduction = process.env.ENV === 'prod' || process.env.ENV === 'staging';\n\n// Cookie configuration\n// Note: SameSite=None requires Secure=true (HTTPS)\n// In dev, use SameSite=Lax with Angular proxy to avoid cross-origin issues\nconst cookieConfig = {\n httpOnly: true,\n secure: isProduction, // Only secure in production (HTTPS)\n sameSite: 'lax' as const, // Lax works for same-origin (Angular proxy in dev, Nginx in prod)\n};\n\n/**\n * Set the access token in the response cookies.\n * @param res - The response object.\n * @param accessToken - The access token to set.\n */\nfunction setAccessToken(res: Response, accessToken: string) {\n\n const decodedToken = decode(accessToken) as JwtPayload;\n \n // decoded.exp is in seconds since epoch\n // Date.now() returns milliseconds since epoch\n // maxAge needs milliseconds remaining\n if (!decodedToken.exp) {\n throw new Error(\"Access token does not contain an expiration time\");\n }\n \n res.cookie('accessToken', accessToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\n/**\n * Set the refresh token in the response cookies.\n * @param res - The response object.\n * @param refreshToken - The refresh token to set.\n */\nfunction setRefreshToken(res: Response, refreshToken: string) {\n\n const decodedToken = decode(refreshToken) as JwtPayload;\n\n if (!decodedToken.exp) {\n throw new Error(\"Refresh token does not contain an expiration time\");\n }\n\n res.cookie('refreshToken', refreshToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\nfunction parseCookies(req: Request) : { [key: string]: string } {\n const cookies = req.headers.cookie;\n if (!cookies) {\n return {};\n }\n return cookies.split(';').reduce((acc: { [key: string]: string }, cookie) => {\n const [key, value] = cookie.split('=').map(s => s.trim());\n acc[key] = value;\n return acc;\n }, {});\n}\n\n/**\n * Set the state token in the response cookies.\n * @param res - The response object.\n * @param stateToken - The state token to set.\n */\nfunction setUrlToken(res: Response, stateToken: string, exp: number) {\n\n\n res.cookie('urlToken', stateToken, {\n ...cookieConfig,\n maxAge: exp\n });\n}\n\nfunction clearCookies(res: Response) {\n const clearConfig = {\n ...cookieConfig,\n path: '/'\n };\n \n res.clearCookie(\"accessToken\", clearConfig);\n res.clearCookie(\"refreshToken\", clearConfig);\n res.clearCookie(\"urlToken\", clearConfig);\n}\n\nexport { setAccessToken, setRefreshToken, parseCookies, clearCookies, setUrlToken};\n", "import { AuthGneissCore, AuthGneissCoreConfig } from \"@core\";\nimport { Request, Response, NextFunction } from \"express\";\nimport { AuthenticatedRequest, Tokens } from \"@core/types\";\nimport { setAccessToken, setRefreshToken, parseCookies, setUrlToken} from \"@utils\";\nimport { AxiosError } from \"axios\";\nimport axios from \"axios\";\nimport { clearCookies } from \"@/utils/storage/cookieHandling\";\n\n\n/**\n * ExpressAuthGneissClient extends AuthGneissCore to provide Express-specific authentication middleware\n * and functionality for handling OAuth2 authentication flow with Gneiss authentication service.\n * \n * @extends AuthGneissCore\n * @example\n * const authClient = new ExpressAuthGneissClient({\n * clientId: 'your-client-id',\n * clientSecret: 'your-client-secret',\n * redirectUrl: 'your-redirect-url'\n * });\n */\nclass ExpressAuthGneissClient extends AuthGneissCore {\n\n private returnUrlStore = new Map<string, string>();\n private readonly URL_STORE_TTL = 10 * 60 * 1000; // 10 minutes\n\n constructor(\n config: AuthGneissCoreConfig\n ) {\n super(config);\n \n // Bind the methods in constructor\n this.requireAuth = this.requireAuth.bind(this);\n this.handleCallBack = this.handleCallBack.bind(this);\n this.loginUser = this.loginUser.bind(this);\n this.logoutUser = this.logoutUser.bind(this);\n this.getUser = this.getUser.bind(this);\n this.deleteUser = this.deleteUser.bind(this);\n this.getUserData = this.getUserData.bind(this);\n this.getLoginUrl = this.getLoginUrl.bind(this);\n this.getLogoutUrl = this.getLogoutUrl.bind(this);\n this.getSignupUrl = this.getSignupUrl.bind(this);\n this.getAuthUrl = this.getAuthUrl.bind(this);\n }\n\n /**\n /**\n * requireAuth is a middleware function that checks if the access token is valid.\n * If the access token is not valid, it attempts to refresh the token using the refresh token.\n * If the refresh token is not valid, it redirects the user to the login page.\n * @template UserT - The type of the user object to attach to the request.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async requireAuth<UserT>(req: Request, res: Response, next: NextFunction): Promise<void> {\n const cookies = parseCookies(req);\n //Check for the existence of the access token\n // console.log(\"DEBUG: cookies\", cookies);\n try {\n const isAccessTokenValid : boolean = await this.validateToken(cookies?.accessToken);\n if (!isAccessTokenValid) { //if the access token is not valid\n //try to refresh the token\n const newAccessToken : string | null = await this.refreshToken(cookies?.refreshToken);\n if (newAccessToken) { // set access token and then call next to proceed to the next middleware/handler\n setAccessToken(res, newAccessToken);\n next()\n }\n else {\n // no access token or valid refresh token, redirect to login with 401 requires login credentials\n res.redirect(401, `${this.loginUrl}?redirect_url=${this.getBase64EncodedCallbackUrl()}`);\n }\n }\n else {\n // access token is valid, continue to the next middleware or route handler after adding user to req\n (req as AuthenticatedRequest<UserT>).user = await this.getUserData(cookies.accessToken);\n next();\n }\n } catch (error) {\n // console.error('Error in requireAuth middleware:', error);\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * getUserData is a middleware function that fetches user data using the access token.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async getUser(req: Request, res: Response, next: NextFunction): Promise<void> {\n await this.requireAuth(req, res, async () => {\n const cookies = parseCookies(req);\n const accessToken = cookies?.accessToken;\n try {\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n console.error('Error in getUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n });\n }\n\n /**\n * handleCallBack is a middleware function that handles the callback from the authentication service.\n * It extracts the auth code from the request URL parameters, exchanges it for tokens, and sets the access and refresh tokens in the response cookies.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async handleCallBack(\n req: Request,\n res: Response,\n next: NextFunction\n ): Promise<void> {\n\n const cookies = parseCookies(req);\n const returnToToken = cookies?.urlToken\n\n try {\n const authCode: string | undefined = req.query.auth_code as string;\n const returnToUrl = this.returnUrlStore.get(returnToToken);\n\n if (!authCode) {\n throw new Error(\"No auth code found in request url parameters\");\n }\n\n const tokens: Tokens = await this.getTokens(authCode);\n \n // Set the access and refresh tokens in the response cookies\n setAccessToken(res, tokens.accessToken);\n setRefreshToken(res, tokens.refreshToken);\n\n if (returnToUrl) {\n // Go to the original request url\n res.redirect(returnToUrl);\n }\n else {\n // Go to the root url\n res.redirect(\"/\")\n }\n } catch (error) {\n // console.error('Error in handleCallBack middleware:', error);\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n console.error(\"DEBUG: error\", error);\n return;\n }\n }\n res.status(500).send('Internal server error');\n console.error(\"DEBUG: error\", error);\n }\n }\n\n /**\n * login is a function that redirects the user to the Gneiss authentication service for authentication.\n * Accepts an optional returnTo query parameter to specify where to redirect after successful login.\n * Falls back to referer header if no returnTo is provided.\n * @param req - The request object.\n * @param res - The response object.\n */\n public loginUser(req: Request, res: Response): void {\n try {\n if (!this.loginUrl) {\n throw new Error('Login URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n\n // Priority: query param > referer header > environment variable\n // In dev with proxy, referer will be the frontend URL (e.g., http://localhost:4200)\n // In staging, FRONTEND_URL should be set to staging frontend URL\n const returnToUrl = \n (req.query.returnTo as string) || \n req.get('referer') || \n process.env.FRONTEND_URL || \n '/'; // Fallback to root path (same origin)\n \n const urlToken = crypto.randomUUID();\n\n // Store the returnToUrl with auto-expiration\n this.returnUrlStore.set(urlToken, returnToUrl);\n setUrlToken(res, urlToken, this.URL_STORE_TTL);\n setTimeout(() => this.returnUrlStore.delete(urlToken), this.URL_STORE_TTL);\n\n //Base64 encode callback url\n const callbackUrl = this.getBase64EncodedCallbackUrl();\n\n res.redirect(this.loginUrl + `?redirect_url=${callbackUrl}`);\n } catch (error) {\n console.error('Error in login middleware:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * logoutUser is a function that redirects the user to the Gneiss logout service.\n * It uses requireAuth to ensure the access token is valid before logout.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async logoutUser(req: Request, res: Response, next: NextFunction): Promise<void> {\n await this.requireAuth(req, res, async () => {\n const cookies = parseCookies(req);\n try {\n await this.logout(cookies?.accessToken);\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\"); // Redirect back to home after logout\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n console.error('Error in logout middleware:', error);\n res.status(500).send('Internal server error');\n }\n });\n }\n\n /**\n * Utility route handler for deleting a user.\n * This ensures that the user is fully logged out before\n * deleting the user's data.\n * \n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async deleteUser(req: Request, res: Response, next: NextFunction): Promise<void> {\n await this.requireAuth(req, res, async () => {\n const cookies = parseCookies(req);\n try {\n await this.logout(cookies?.accessToken);\n clearCookies(res);\n await this.deleteUserData(cookies?.accessToken);\n res.redirect(\"/\");\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n console.error('Error in deleteUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n });\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_axios", "dotenv", "axios", "import_axios", "config"]
|
|
7
7
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { AxiosError } from "axios";
|
|
|
6
6
|
// src/config.ts
|
|
7
7
|
var config = {
|
|
8
8
|
authUrl: process.env.ENV === "prod" ? "https://auth.gneiss.io" : process.env.ENV === "staging" ? "https://auth.gneiss.io/testing" : "http://localhost:5000",
|
|
9
|
-
internalAuthUrl: process.env.ENV === "prod" ? "http://auth:
|
|
9
|
+
internalAuthUrl: process.env.ENV === "prod" ? "http://auth:5000" : process.env.ENV === "staging" ? "http://auth:5000/testing" : "http://auth:5000"
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/core/AuthGneissCore.ts
|
|
@@ -277,10 +277,13 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
277
277
|
}
|
|
278
278
|
} catch (error) {
|
|
279
279
|
if (error instanceof AxiosError2) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
280
|
+
switch (error.response?.status) {
|
|
281
|
+
default:
|
|
282
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
283
285
|
}
|
|
286
|
+
res.status(500).send("Internal server error");
|
|
284
287
|
}
|
|
285
288
|
}
|
|
286
289
|
/**
|
|
@@ -289,23 +292,25 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
289
292
|
* @param res - The response object.
|
|
290
293
|
* @param next - The next middleware function.
|
|
291
294
|
*/
|
|
292
|
-
async getUser(req, res) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
295
|
+
async getUser(req, res, next) {
|
|
296
|
+
await this.requireAuth(req, res, async () => {
|
|
297
|
+
const cookies = parseCookies(req);
|
|
298
|
+
const accessToken = cookies?.accessToken;
|
|
299
|
+
try {
|
|
300
|
+
const userData = await this.getUserData(accessToken);
|
|
301
|
+
res.status(200).send(userData);
|
|
302
|
+
} catch (error) {
|
|
303
|
+
if (error instanceof AxiosError2) {
|
|
304
|
+
switch (error.response?.status) {
|
|
305
|
+
default:
|
|
306
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
304
309
|
}
|
|
310
|
+
console.error("Error in getUser utility function:", error);
|
|
311
|
+
res.status(500).send("Internal server error");
|
|
305
312
|
}
|
|
306
|
-
|
|
307
|
-
res.status(500).send("Internal server error");
|
|
308
|
-
}
|
|
313
|
+
});
|
|
309
314
|
}
|
|
310
315
|
/**
|
|
311
316
|
* handleCallBack is a middleware function that handles the callback from the authentication service.
|
|
@@ -333,12 +338,15 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
333
338
|
}
|
|
334
339
|
} catch (error) {
|
|
335
340
|
if (error instanceof AxiosError2) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
+
switch (error.response?.status) {
|
|
342
|
+
default:
|
|
343
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
344
|
+
console.error("DEBUG: error", error);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
341
347
|
}
|
|
348
|
+
res.status(500).send("Internal server error");
|
|
349
|
+
console.error("DEBUG: error", error);
|
|
342
350
|
}
|
|
343
351
|
}
|
|
344
352
|
/**
|
|
@@ -367,50 +375,60 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
|
|
|
367
375
|
}
|
|
368
376
|
/**
|
|
369
377
|
* logoutUser is a function that redirects the user to the Gneiss logout service.
|
|
378
|
+
* It uses requireAuth to ensure the access token is valid before logout.
|
|
370
379
|
* @param req - The request object.
|
|
371
380
|
* @param res - The response object.
|
|
381
|
+
* @param next - The next middleware function.
|
|
372
382
|
*/
|
|
373
|
-
logoutUser(req, res) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
383
|
+
async logoutUser(req, res, next) {
|
|
384
|
+
await this.requireAuth(req, res, async () => {
|
|
385
|
+
const cookies = parseCookies(req);
|
|
386
|
+
try {
|
|
387
|
+
await this.logout(cookies?.accessToken);
|
|
388
|
+
clearCookies(res);
|
|
389
|
+
res.redirect("/");
|
|
390
|
+
} catch (error) {
|
|
391
|
+
if (error instanceof AxiosError2) {
|
|
392
|
+
switch (error.response?.status) {
|
|
393
|
+
default:
|
|
394
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
384
397
|
}
|
|
398
|
+
console.error("Error in logout middleware:", error);
|
|
399
|
+
res.status(500).send("Internal server error");
|
|
385
400
|
}
|
|
386
|
-
|
|
387
|
-
res.status(500).send("Internal server error");
|
|
388
|
-
}
|
|
401
|
+
});
|
|
389
402
|
}
|
|
390
403
|
/**
|
|
391
|
-
* Utility route handler for deleting a user
|
|
392
|
-
* This ensures that the user is fully logged out before
|
|
393
|
-
* deleting the user's data
|
|
404
|
+
* Utility route handler for deleting a user.
|
|
405
|
+
* This ensures that the user is fully logged out before
|
|
406
|
+
* deleting the user's data.
|
|
394
407
|
*
|
|
395
408
|
* @param req - The request object.
|
|
396
409
|
* @param res - The response object.
|
|
410
|
+
* @param next - The next middleware function.
|
|
397
411
|
*/
|
|
398
|
-
deleteUser(req, res) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
412
|
+
async deleteUser(req, res, next) {
|
|
413
|
+
await this.requireAuth(req, res, async () => {
|
|
414
|
+
const cookies = parseCookies(req);
|
|
415
|
+
try {
|
|
416
|
+
await this.logout(cookies?.accessToken);
|
|
417
|
+
clearCookies(res);
|
|
418
|
+
await this.deleteUserData(cookies?.accessToken);
|
|
419
|
+
res.redirect("/");
|
|
420
|
+
} catch (error) {
|
|
421
|
+
if (error instanceof AxiosError2) {
|
|
422
|
+
switch (error.response?.status) {
|
|
423
|
+
default:
|
|
424
|
+
res.status(error.response?.status || 500).send(error.response?.data || "Internal server error");
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
409
427
|
}
|
|
428
|
+
console.error("Error in deleteUser utility function:", error);
|
|
429
|
+
res.status(500).send("Internal server error");
|
|
410
430
|
}
|
|
411
|
-
|
|
412
|
-
res.status(500).send("Internal server error");
|
|
413
|
-
}
|
|
431
|
+
});
|
|
414
432
|
}
|
|
415
433
|
};
|
|
416
434
|
var ExpressAuthGneissClient_default = ExpressAuthGneissClient;
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/AuthGneissCore.ts", "../../src/config.ts", "../../src/utils/storage/cookieHandling.ts", "../../src/frameworks/express/middleware/ExpressAuthGneissClient.ts"],
|
|
4
|
-
"sourcesContent": ["import { AuthGneissCoreConfig } from \"@core/types\";\nimport axios, { AxiosResponse } from \"axios\";\nimport { Tokens } from \"@core/types\";\nimport dotenv from \"dotenv\";\nimport { AxiosError } from \"axios\";\nimport { config as genConfig } from \"@/config\";\nimport { AuthGneissGeneralConfig } from \"@/config\";\n\n//load environment variables if not already set\nif (!process.env.ENV) {\n dotenv.config();\n}\n\n/**\n * AuthGneissCore provides core functionality for OAuth2 authentication flow with Gneiss authentication service.\n * It handles token exchange, token refresh, user data fetching, and token validation.\n * \n * This class serves as a base class that can be extended by framework-specific implementations\n * to provide authentication middleware and handlers.\n */\nclass AuthGneissCore {\n protected config: AuthGneissCoreConfig & AuthGneissGeneralConfig; // Configuration object\n protected authUrl : string;\n protected loginUrl : string;\n protected logoutUrl : string;\n protected signupUrl : string;\n protected callbackUrl : string;\n protected internalAuthUrl : string;\n\n constructor(\n devConfig: AuthGneissCoreConfig,\n generalConfig: AuthGneissGeneralConfig = genConfig\n ) {\n\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.internalAuthUrl = this.config.internalAuthUrl;\n this.loginUrl = `${this.authUrl}/auth/login` // Login URL\n this.logoutUrl = `${this.internalAuthUrl}/auth/logout` // Logout URL\n this.signupUrl = `${this.authUrl}/auth/register` // Signup/register URL\n this.callbackUrl = `${this.config.baseClientUrl}${this.config.callbackRoute}`\n\n //check if environment variables are set\n let errorMsgs = [];\n if (!process.env.ENV) {\n errorMsgs.push(\"ENV is not set in environment variables\");\n }\n if (errorMsgs.length > 0) {\n throw new Error(errorMsgs.join(\"\\n\"));\n }\n }\n\n public getBase64EncodedCallbackUrl(): string {\n return Buffer.from(this.callbackUrl).toString('base64')\n }\n\n /**\n * getTokens is a method that exchanges an authentication code for access and refresh tokens.\n * The client id and secret are passed as basic auth headers to authenticate the client itself.\n * @param authCode - The authentication code received from the Gneiss authentication service.\n * @returns A promise that resolves to an object containing the access and refresh tokens.\n */\n protected async getTokens(authCode : string) : Promise<Tokens> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/access_token?auth_code=${authCode}`;\n //Encode in base64 before transport\n const encodedClientId = btoa(this.config.clientId);\n const encodedClientSecret = btoa(this.config.clientSecret);\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Basic ${encodedClientId}:${encodedClientSecret}`\n }\n });\n return {\n accessToken: response.data.access_token,\n refreshToken: response.data.refresh_token,\n tokenType: response.data.token_type\n } as Tokens;\n } catch (error) {\n // console.error(\"Error in getTokens:\", error);\n throw error;\n }\n }\n \n /**\n * refreshToken is a method that refreshes the access token using the refresh token.\n * @param refreshToken - The refresh token to be used for token refresh.\n * @returns A promise that resolves to the refreshed access token.\n */\n protected async refreshToken(refreshToken: string): Promise<string | null> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/refresh`;\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Bearer ${refreshToken}`\n }\n });\n return response.data.access_token as string;\n } catch (error) {\n // console.error(\"Error in refreshToken:\", error);\n return null;\n }\n }\n\n protected async logout(accessToken : string) {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n await axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n }\n \n /**\n * getUserData is a method that fetches user data using the access token.\n * @param accessToken - The access token to be used for user data fetching.\n * @returns A promise that resolves to the user data.\n */\n public async getUserData(accessToken: string) {\n const url : string = `${this.internalAuthUrl}/resource/user_data`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n if (response.status === 200) {\n return response.data;\n }\n throw new Error(\"Failed to fetch user data\");\n }\n \n /**\n * validateToken is a method that validates the access token.\n * @param token - The access token to be validated.\n * @returns A promise that resolves to a boolean indicating the validity of the token.\n */\n protected async validateToken(token: string): Promise<boolean> {\n try {\n console.log(\"DEBUG: token\", token);\n // Token validation logic\n if (!token) {\n return false;\n }\n const url : string = `${this.internalAuthUrl}/auth/validate_token`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${token}`\n }\n });\n return response.status === 200;\n } catch (error) {\n // console.error(\"Error in validateToken:\", error);\n if (error instanceof AxiosError && error.response?.status === 401) {\n return false;\n } else {\n throw error;\n }\n }\n }\n\n /**\n * getLoginUrl is a method that returns the login URL.\n * @returns The login URL.\n */\n public getLoginUrl() : string | undefined {\n return this.loginUrl;\n }\n\n /**\n * Returns the base auth URL.\n * @returns The base auth URL.\n */\n public getAuthUrl(): string | undefined {\n return this.authUrl;\n }\n\n /**\n * Returns the logout URL.\n * @returns The logout URL.\n */\n public getLogoutUrl(): string | undefined {\n return this.logoutUrl;\n }\n\n /**\n * Returns the signup URL.\n * @returns The signup URL.\n */\n public getSignupUrl(): string | undefined {\n return this.signupUrl;\n }\n\n /**\n * deleteUser deletes the user\n * */\n protected async deleteUserData(accessToken : string) : Promise<object> {\n const response : AxiosResponse = await axios.post(`${this.internalAuthUrl}/resource/delete_user`, {}, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n } \n });\n return response.data;\n }\n}\n\nexport default AuthGneissCore;\n", "export type AuthGneissGeneralConfig = {\n authUrl: string // used by the browser\n internalAuthUrl: string // used internally within the same docker network\n}\n\nexport const config : AuthGneissGeneralConfig = {\n authUrl: process.env.ENV === \"prod\" ? \"https://auth.gneiss.io\" : \n process.env.ENV === \"staging\" ? \"https://auth.gneiss.io/testing\" : \"http://localhost:5000\",\n internalAuthUrl: process.env.ENV === \"prod\" ? \"http://auth:45443\" : \n process.env.ENV === \"staging\" ? \"http://auth:44443/testing\" : \"http://auth:5000\"\n}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\n\n// Helper to determine if we're in production\nconst isProduction = process.env.ENV === 'prod' || process.env.ENV === 'staging';\n\n// Cookie configuration\n// Note: SameSite=None requires Secure=true (HTTPS)\n// In dev, use SameSite=Lax with Angular proxy to avoid cross-origin issues\nconst cookieConfig = {\n httpOnly: true,\n secure: isProduction, // Only secure in production (HTTPS)\n sameSite: 'lax' as const, // Lax works for same-origin (Angular proxy in dev, Nginx in prod)\n};\n\n/**\n * Set the access token in the response cookies.\n * @param res - The response object.\n * @param accessToken - The access token to set.\n */\nfunction setAccessToken(res: Response, accessToken: string) {\n\n const decodedToken = decode(accessToken) as JwtPayload;\n \n // decoded.exp is in seconds since epoch\n // Date.now() returns milliseconds since epoch\n // maxAge needs milliseconds remaining\n if (!decodedToken.exp) {\n throw new Error(\"Access token does not contain an expiration time\");\n }\n \n res.cookie('accessToken', accessToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\n/**\n * Set the refresh token in the response cookies.\n * @param res - The response object.\n * @param refreshToken - The refresh token to set.\n */\nfunction setRefreshToken(res: Response, refreshToken: string) {\n\n const decodedToken = decode(refreshToken) as JwtPayload;\n\n if (!decodedToken.exp) {\n throw new Error(\"Refresh token does not contain an expiration time\");\n }\n\n res.cookie('refreshToken', refreshToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\nfunction parseCookies(req: Request) : { [key: string]: string } {\n const cookies = req.headers.cookie;\n if (!cookies) {\n return {};\n }\n return cookies.split(';').reduce((acc: { [key: string]: string }, cookie) => {\n const [key, value] = cookie.split('=').map(s => s.trim());\n acc[key] = value;\n return acc;\n }, {});\n}\n\n/**\n * Set the state token in the response cookies.\n * @param res - The response object.\n * @param stateToken - The state token to set.\n */\nfunction setUrlToken(res: Response, stateToken: string, exp: number) {\n\n\n res.cookie('urlToken', stateToken, {\n ...cookieConfig,\n maxAge: exp\n });\n}\n\nfunction clearCookies(res: Response) {\n const clearConfig = {\n ...cookieConfig,\n path: '/'\n };\n \n res.clearCookie(\"accessToken\", clearConfig);\n res.clearCookie(\"refreshToken\", clearConfig);\n res.clearCookie(\"urlToken\", clearConfig);\n}\n\nexport { setAccessToken, setRefreshToken, parseCookies, clearCookies, setUrlToken};\n", "import { AuthGneissCore, AuthGneissCoreConfig } from \"@core\";\nimport { Request, Response, NextFunction } from \"express\";\nimport { AuthenticatedRequest, Tokens } from \"@core/types\";\nimport { setAccessToken, setRefreshToken, parseCookies, setUrlToken} from \"@utils\";\nimport { AxiosError } from \"axios\";\nimport axios from \"axios\";\nimport { clearCookies } from \"@/utils/storage/cookieHandling\";\n\n\n/**\n * ExpressAuthGneissClient extends AuthGneissCore to provide Express-specific authentication middleware\n * and functionality for handling OAuth2 authentication flow with Gneiss authentication service.\n * \n * @extends AuthGneissCore\n * @example\n * const authClient = new ExpressAuthGneissClient({\n * clientId: 'your-client-id',\n * clientSecret: 'your-client-secret',\n * redirectUrl: 'your-redirect-url'\n * });\n */\nclass ExpressAuthGneissClient extends AuthGneissCore {\n\n private returnUrlStore = new Map<string, string>();\n private readonly URL_STORE_TTL = 10 * 60 * 1000; // 10 minutes\n\n constructor(\n config: AuthGneissCoreConfig\n ) {\n super(config);\n \n // Bind the methods in constructor\n this.requireAuth = this.requireAuth.bind(this);\n this.handleCallBack = this.handleCallBack.bind(this);\n this.loginUser = this.loginUser.bind(this);\n this.logoutUser = this.logoutUser.bind(this);\n this.getUser = this.getUser.bind(this);\n this.deleteUser = this.deleteUser.bind(this);\n this.getUserData = this.getUserData.bind(this);\n this.getLoginUrl = this.getLoginUrl.bind(this);\n this.getLogoutUrl = this.getLogoutUrl.bind(this);\n this.getSignupUrl = this.getSignupUrl.bind(this);\n this.getAuthUrl = this.getAuthUrl.bind(this);\n }\n\n /**\n /**\n * requireAuth is a middleware function that checks if the access token is valid.\n * If the access token is not valid, it attempts to refresh the token using the refresh token.\n * If the refresh token is not valid, it redirects the user to the login page.\n * @template UserT - The type of the user object to attach to the request.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async requireAuth<UserT>(req: Request, res: Response, next: NextFunction): Promise<void> {\n const cookies = parseCookies(req);\n //Check for the existence of the access token\n // console.log(\"DEBUG: cookies\", cookies);\n try {\n const isAccessTokenValid : boolean = await this.validateToken(cookies?.accessToken);\n if (!isAccessTokenValid) { //if the access token is not valid\n //try to refresh the token\n const newAccessToken : string | null = await this.refreshToken(cookies?.refreshToken);\n if (newAccessToken) { // set access token and then call next to proceed to the next middleware/handler\n setAccessToken(res, newAccessToken);\n next()\n }\n else {\n // no access token or valid refresh token, redirect to login with 401 requires login credentials\n res.redirect(401, `${this.loginUrl}?redirect_url=${this.getBase64EncodedCallbackUrl()}`);\n }\n }\n else {\n // access token is valid, continue to the next middleware or route handler after adding user to req\n (req as AuthenticatedRequest<UserT>).user = await this.getUserData(cookies.accessToken);\n next();\n }\n } catch (error) {\n // console.error('Error in requireAuth middleware:', error);\n if (error instanceof AxiosError) {\n res.status((error as AxiosError).response?.status || 500).send((error as AxiosError).response?.data || 'Internal server error');\n } else {\n res.status(500).send('Internal server error');\n }\n }\n }\n\n /**\n * getUserData is a middleware function that fetches user data using the access token.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async getUser(req: Request, res: Response): Promise<void> {\n const cookies = parseCookies(req);\n const accessToken = cookies?.accessToken;\n try {\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n case 401:\n res.redirect(401, this.loginUrl);\n return;\n }\n }\n console.error('Error in getUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * handleCallBack is a middleware function that handles the callback from the authentication service.\n * It extracts the auth code from the request URL parameters, exchanges it for tokens, and sets the access and refresh tokens in the response cookies.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async handleCallBack(\n req: Request,\n res: Response,\n next: NextFunction\n ): Promise<void> {\n\n const cookies = parseCookies(req);\n const returnToToken = cookies?.urlToken\n\n try {\n const authCode: string | undefined = req.query.auth_code as string;\n const returnToUrl = this.returnUrlStore.get(returnToToken);\n\n if (!authCode) {\n throw new Error(\"No auth code found in request url parameters\");\n }\n\n const tokens: Tokens = await this.getTokens(authCode);\n \n // Set the access and refresh tokens in the response cookies\n setAccessToken(res, tokens.accessToken);\n setRefreshToken(res, tokens.refreshToken);\n\n if (returnToUrl) {\n // Go to the original request url\n res.redirect(returnToUrl);\n }\n else {\n // Go to the root url\n res.redirect(\"/\")\n }\n } catch (error) {\n // console.error('Error in handleCallBack middleware:', error);\n if (error instanceof AxiosError) {\n res.status((error as AxiosError).response?.status || 500).send((error as AxiosError).response?.data || 'Internal server error');\n console.error(\"DEBUG: error\", error);\n } else {\n res.status(500).send('Internal server error');\n console.error(\"DEBUG: error\", error);\n }\n }\n }\n\n /**\n * login is a function that redirects the user to the Gneiss authentication service for authentication.\n * Accepts an optional returnTo query parameter to specify where to redirect after successful login.\n * Falls back to referer header if no returnTo is provided.\n * @param req - The request object.\n * @param res - The response object.\n */\n public loginUser(req: Request, res: Response): void {\n try {\n if (!this.loginUrl) {\n throw new Error('Login URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n\n // Priority: query param > referer header > environment variable\n // In dev with proxy, referer will be the frontend URL (e.g., http://localhost:4200)\n // In staging, FRONTEND_URL should be set to staging frontend URL\n const returnToUrl = \n (req.query.returnTo as string) || \n req.get('referer') || \n process.env.FRONTEND_URL || \n '/'; // Fallback to root path (same origin)\n \n const urlToken = crypto.randomUUID();\n\n // Store the returnToUrl with auto-expiration\n this.returnUrlStore.set(urlToken, returnToUrl);\n setUrlToken(res, urlToken, this.URL_STORE_TTL);\n setTimeout(() => this.returnUrlStore.delete(urlToken), this.URL_STORE_TTL);\n\n //Base64 encode callback url\n const callbackUrl = this.getBase64EncodedCallbackUrl();\n\n res.redirect(this.loginUrl + `?redirect_url=${callbackUrl}`);\n } catch (error) {\n console.error('Error in login middleware:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * logoutUser is a function that redirects the user to the Gneiss logout service.\n * @param req - The request object.\n * @param res - The response object.\n */\n public logoutUser(req: Request, res: Response): void {\n const cookies = parseCookies(req);\n try {\n this.logout(cookies?.accessToken)\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\") // Redirect back to home after logout\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n case 401:\n res.redirect(401, this.loginUrl)\n }\n }\n console.error('Error in logout middleware:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * Utility route handler for deleting a user\n * This ensures that the user is fully logged out before \n * deleting the user's data\n * \n * @param req - The request object.\n * @param res - The response object.\n */\n public deleteUser(req: Request, res: Response) {\n const cookies = parseCookies(req);\n try {\n this.logoutUser(req, res);\n this.deleteUserData(cookies?.accessToken);\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n case 401:\n res.redirect(401, this.loginUrl);\n return;\n }\n }\n console.error('Error in deleteUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
|
|
5
|
-
"mappings": ";AACA,OAAO,WAA8B;AAErC,OAAO,YAAY;AACnB,SAAS,kBAAkB;;;ACCpB,IAAM,SAAmC;AAAA,EAC5C,SAAS,QAAQ,IAAI,QAAQ,SAAS,2BACtC,QAAQ,IAAI,QAAQ,YAAY,mCAAmC;AAAA,EACnE,iBAAiB,QAAQ,IAAI,QAAQ,SAAS,
|
|
4
|
+
"sourcesContent": ["import { AuthGneissCoreConfig } from \"@core/types\";\nimport axios, { AxiosResponse } from \"axios\";\nimport { Tokens } from \"@core/types\";\nimport dotenv from \"dotenv\";\nimport { AxiosError } from \"axios\";\nimport { config as genConfig } from \"@/config\";\nimport { AuthGneissGeneralConfig } from \"@/config\";\n\n//load environment variables if not already set\nif (!process.env.ENV) {\n dotenv.config();\n}\n\n/**\n * AuthGneissCore provides core functionality for OAuth2 authentication flow with Gneiss authentication service.\n * It handles token exchange, token refresh, user data fetching, and token validation.\n * \n * This class serves as a base class that can be extended by framework-specific implementations\n * to provide authentication middleware and handlers.\n */\nclass AuthGneissCore {\n protected config: AuthGneissCoreConfig & AuthGneissGeneralConfig; // Configuration object\n protected authUrl : string;\n protected loginUrl : string;\n protected logoutUrl : string;\n protected signupUrl : string;\n protected callbackUrl : string;\n protected internalAuthUrl : string;\n\n constructor(\n devConfig: AuthGneissCoreConfig,\n generalConfig: AuthGneissGeneralConfig = genConfig\n ) {\n\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.internalAuthUrl = this.config.internalAuthUrl;\n this.loginUrl = `${this.authUrl}/auth/login` // Login URL\n this.logoutUrl = `${this.internalAuthUrl}/auth/logout` // Logout URL\n this.signupUrl = `${this.authUrl}/auth/register` // Signup/register URL\n this.callbackUrl = `${this.config.baseClientUrl}${this.config.callbackRoute}`\n\n //check if environment variables are set\n let errorMsgs = [];\n if (!process.env.ENV) {\n errorMsgs.push(\"ENV is not set in environment variables\");\n }\n if (errorMsgs.length > 0) {\n throw new Error(errorMsgs.join(\"\\n\"));\n }\n }\n\n public getBase64EncodedCallbackUrl(): string {\n return Buffer.from(this.callbackUrl).toString('base64')\n }\n\n /**\n * getTokens is a method that exchanges an authentication code for access and refresh tokens.\n * The client id and secret are passed as basic auth headers to authenticate the client itself.\n * @param authCode - The authentication code received from the Gneiss authentication service.\n * @returns A promise that resolves to an object containing the access and refresh tokens.\n */\n protected async getTokens(authCode : string) : Promise<Tokens> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/access_token?auth_code=${authCode}`;\n //Encode in base64 before transport\n const encodedClientId = btoa(this.config.clientId);\n const encodedClientSecret = btoa(this.config.clientSecret);\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Basic ${encodedClientId}:${encodedClientSecret}`\n }\n });\n return {\n accessToken: response.data.access_token,\n refreshToken: response.data.refresh_token,\n tokenType: response.data.token_type\n } as Tokens;\n } catch (error) {\n // console.error(\"Error in getTokens:\", error);\n throw error;\n }\n }\n \n /**\n * refreshToken is a method that refreshes the access token using the refresh token.\n * @param refreshToken - The refresh token to be used for token refresh.\n * @returns A promise that resolves to the refreshed access token.\n */\n protected async refreshToken(refreshToken: string): Promise<string | null> {\n try {\n const url : string = `${this.internalAuthUrl}/auth/refresh`;\n const response : AxiosResponse = await axios.post(url, {}, {\n headers: {\n \"Authorization\": `Bearer ${refreshToken}`\n }\n });\n return response.data.access_token as string;\n } catch (error) {\n // console.error(\"Error in refreshToken:\", error);\n return null;\n }\n }\n\n protected async logout(accessToken : string) {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n await axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n }\n \n /**\n * getUserData is a method that fetches user data using the access token.\n * @param accessToken - The access token to be used for user data fetching.\n * @returns A promise that resolves to the user data.\n */\n public async getUserData(accessToken: string) {\n const url : string = `${this.internalAuthUrl}/resource/user_data`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n if (response.status === 200) {\n return response.data;\n }\n throw new Error(\"Failed to fetch user data\");\n }\n \n /**\n * validateToken is a method that validates the access token.\n * @param token - The access token to be validated.\n * @returns A promise that resolves to a boolean indicating the validity of the token.\n */\n protected async validateToken(token: string): Promise<boolean> {\n try {\n console.log(\"DEBUG: token\", token);\n // Token validation logic\n if (!token) {\n return false;\n }\n const url : string = `${this.internalAuthUrl}/auth/validate_token`;\n const response : AxiosResponse = await axios.get(url, {\n headers: {\n \"Authorization\": `Bearer ${token}`\n }\n });\n return response.status === 200;\n } catch (error) {\n // console.error(\"Error in validateToken:\", error);\n if (error instanceof AxiosError && error.response?.status === 401) {\n return false;\n } else {\n throw error;\n }\n }\n }\n\n /**\n * getLoginUrl is a method that returns the login URL.\n * @returns The login URL.\n */\n public getLoginUrl() : string | undefined {\n return this.loginUrl;\n }\n\n /**\n * Returns the base auth URL.\n * @returns The base auth URL.\n */\n public getAuthUrl(): string | undefined {\n return this.authUrl;\n }\n\n /**\n * Returns the logout URL.\n * @returns The logout URL.\n */\n public getLogoutUrl(): string | undefined {\n return this.logoutUrl;\n }\n\n /**\n * Returns the signup URL.\n * @returns The signup URL.\n */\n public getSignupUrl(): string | undefined {\n return this.signupUrl;\n }\n\n /**\n * deleteUser deletes the user\n * */\n protected async deleteUserData(accessToken : string) : Promise<object> {\n const response : AxiosResponse = await axios.post(`${this.internalAuthUrl}/resource/delete_user`, {}, {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n } \n });\n return response.data;\n }\n}\n\nexport default AuthGneissCore;\n", "export type AuthGneissGeneralConfig = {\n authUrl: string // used by the browser\n internalAuthUrl: string // used internally within the same docker network\n}\n\nexport const config : AuthGneissGeneralConfig = {\n authUrl: process.env.ENV === \"prod\" ? \"https://auth.gneiss.io\" : \n process.env.ENV === \"staging\" ? \"https://auth.gneiss.io/testing\" : \"http://localhost:5000\",\n internalAuthUrl: process.env.ENV === \"prod\" ? \"http://auth:5000\" : \n process.env.ENV === \"staging\" ? \"http://auth:5000/testing\" : \"http://auth:5000\"\n}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\n\n// Helper to determine if we're in production\nconst isProduction = process.env.ENV === 'prod' || process.env.ENV === 'staging';\n\n// Cookie configuration\n// Note: SameSite=None requires Secure=true (HTTPS)\n// In dev, use SameSite=Lax with Angular proxy to avoid cross-origin issues\nconst cookieConfig = {\n httpOnly: true,\n secure: isProduction, // Only secure in production (HTTPS)\n sameSite: 'lax' as const, // Lax works for same-origin (Angular proxy in dev, Nginx in prod)\n};\n\n/**\n * Set the access token in the response cookies.\n * @param res - The response object.\n * @param accessToken - The access token to set.\n */\nfunction setAccessToken(res: Response, accessToken: string) {\n\n const decodedToken = decode(accessToken) as JwtPayload;\n \n // decoded.exp is in seconds since epoch\n // Date.now() returns milliseconds since epoch\n // maxAge needs milliseconds remaining\n if (!decodedToken.exp) {\n throw new Error(\"Access token does not contain an expiration time\");\n }\n \n res.cookie('accessToken', accessToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\n/**\n * Set the refresh token in the response cookies.\n * @param res - The response object.\n * @param refreshToken - The refresh token to set.\n */\nfunction setRefreshToken(res: Response, refreshToken: string) {\n\n const decodedToken = decode(refreshToken) as JwtPayload;\n\n if (!decodedToken.exp) {\n throw new Error(\"Refresh token does not contain an expiration time\");\n }\n\n res.cookie('refreshToken', refreshToken, {\n ...cookieConfig,\n maxAge: (decodedToken.exp * 1000) - Date.now()\n });\n}\n\nfunction parseCookies(req: Request) : { [key: string]: string } {\n const cookies = req.headers.cookie;\n if (!cookies) {\n return {};\n }\n return cookies.split(';').reduce((acc: { [key: string]: string }, cookie) => {\n const [key, value] = cookie.split('=').map(s => s.trim());\n acc[key] = value;\n return acc;\n }, {});\n}\n\n/**\n * Set the state token in the response cookies.\n * @param res - The response object.\n * @param stateToken - The state token to set.\n */\nfunction setUrlToken(res: Response, stateToken: string, exp: number) {\n\n\n res.cookie('urlToken', stateToken, {\n ...cookieConfig,\n maxAge: exp\n });\n}\n\nfunction clearCookies(res: Response) {\n const clearConfig = {\n ...cookieConfig,\n path: '/'\n };\n \n res.clearCookie(\"accessToken\", clearConfig);\n res.clearCookie(\"refreshToken\", clearConfig);\n res.clearCookie(\"urlToken\", clearConfig);\n}\n\nexport { setAccessToken, setRefreshToken, parseCookies, clearCookies, setUrlToken};\n", "import { AuthGneissCore, AuthGneissCoreConfig } from \"@core\";\nimport { Request, Response, NextFunction } from \"express\";\nimport { AuthenticatedRequest, Tokens } from \"@core/types\";\nimport { setAccessToken, setRefreshToken, parseCookies, setUrlToken} from \"@utils\";\nimport { AxiosError } from \"axios\";\nimport axios from \"axios\";\nimport { clearCookies } from \"@/utils/storage/cookieHandling\";\n\n\n/**\n * ExpressAuthGneissClient extends AuthGneissCore to provide Express-specific authentication middleware\n * and functionality for handling OAuth2 authentication flow with Gneiss authentication service.\n * \n * @extends AuthGneissCore\n * @example\n * const authClient = new ExpressAuthGneissClient({\n * clientId: 'your-client-id',\n * clientSecret: 'your-client-secret',\n * redirectUrl: 'your-redirect-url'\n * });\n */\nclass ExpressAuthGneissClient extends AuthGneissCore {\n\n private returnUrlStore = new Map<string, string>();\n private readonly URL_STORE_TTL = 10 * 60 * 1000; // 10 minutes\n\n constructor(\n config: AuthGneissCoreConfig\n ) {\n super(config);\n \n // Bind the methods in constructor\n this.requireAuth = this.requireAuth.bind(this);\n this.handleCallBack = this.handleCallBack.bind(this);\n this.loginUser = this.loginUser.bind(this);\n this.logoutUser = this.logoutUser.bind(this);\n this.getUser = this.getUser.bind(this);\n this.deleteUser = this.deleteUser.bind(this);\n this.getUserData = this.getUserData.bind(this);\n this.getLoginUrl = this.getLoginUrl.bind(this);\n this.getLogoutUrl = this.getLogoutUrl.bind(this);\n this.getSignupUrl = this.getSignupUrl.bind(this);\n this.getAuthUrl = this.getAuthUrl.bind(this);\n }\n\n /**\n /**\n * requireAuth is a middleware function that checks if the access token is valid.\n * If the access token is not valid, it attempts to refresh the token using the refresh token.\n * If the refresh token is not valid, it redirects the user to the login page.\n * @template UserT - The type of the user object to attach to the request.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async requireAuth<UserT>(req: Request, res: Response, next: NextFunction): Promise<void> {\n const cookies = parseCookies(req);\n //Check for the existence of the access token\n // console.log(\"DEBUG: cookies\", cookies);\n try {\n const isAccessTokenValid : boolean = await this.validateToken(cookies?.accessToken);\n if (!isAccessTokenValid) { //if the access token is not valid\n //try to refresh the token\n const newAccessToken : string | null = await this.refreshToken(cookies?.refreshToken);\n if (newAccessToken) { // set access token and then call next to proceed to the next middleware/handler\n setAccessToken(res, newAccessToken);\n next()\n }\n else {\n // no access token or valid refresh token, redirect to login with 401 requires login credentials\n res.redirect(401, `${this.loginUrl}?redirect_url=${this.getBase64EncodedCallbackUrl()}`);\n }\n }\n else {\n // access token is valid, continue to the next middleware or route handler after adding user to req\n (req as AuthenticatedRequest<UserT>).user = await this.getUserData(cookies.accessToken);\n next();\n }\n } catch (error) {\n // console.error('Error in requireAuth middleware:', error);\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * getUserData is a middleware function that fetches user data using the access token.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async getUser(req: Request, res: Response, next: NextFunction): Promise<void> {\n await this.requireAuth(req, res, async () => {\n const cookies = parseCookies(req);\n const accessToken = cookies?.accessToken;\n try {\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n console.error('Error in getUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n });\n }\n\n /**\n * handleCallBack is a middleware function that handles the callback from the authentication service.\n * It extracts the auth code from the request URL parameters, exchanges it for tokens, and sets the access and refresh tokens in the response cookies.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async handleCallBack(\n req: Request,\n res: Response,\n next: NextFunction\n ): Promise<void> {\n\n const cookies = parseCookies(req);\n const returnToToken = cookies?.urlToken\n\n try {\n const authCode: string | undefined = req.query.auth_code as string;\n const returnToUrl = this.returnUrlStore.get(returnToToken);\n\n if (!authCode) {\n throw new Error(\"No auth code found in request url parameters\");\n }\n\n const tokens: Tokens = await this.getTokens(authCode);\n \n // Set the access and refresh tokens in the response cookies\n setAccessToken(res, tokens.accessToken);\n setRefreshToken(res, tokens.refreshToken);\n\n if (returnToUrl) {\n // Go to the original request url\n res.redirect(returnToUrl);\n }\n else {\n // Go to the root url\n res.redirect(\"/\")\n }\n } catch (error) {\n // console.error('Error in handleCallBack middleware:', error);\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n console.error(\"DEBUG: error\", error);\n return;\n }\n }\n res.status(500).send('Internal server error');\n console.error(\"DEBUG: error\", error);\n }\n }\n\n /**\n * login is a function that redirects the user to the Gneiss authentication service for authentication.\n * Accepts an optional returnTo query parameter to specify where to redirect after successful login.\n * Falls back to referer header if no returnTo is provided.\n * @param req - The request object.\n * @param res - The response object.\n */\n public loginUser(req: Request, res: Response): void {\n try {\n if (!this.loginUrl) {\n throw new Error('Login URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n\n // Priority: query param > referer header > environment variable\n // In dev with proxy, referer will be the frontend URL (e.g., http://localhost:4200)\n // In staging, FRONTEND_URL should be set to staging frontend URL\n const returnToUrl = \n (req.query.returnTo as string) || \n req.get('referer') || \n process.env.FRONTEND_URL || \n '/'; // Fallback to root path (same origin)\n \n const urlToken = crypto.randomUUID();\n\n // Store the returnToUrl with auto-expiration\n this.returnUrlStore.set(urlToken, returnToUrl);\n setUrlToken(res, urlToken, this.URL_STORE_TTL);\n setTimeout(() => this.returnUrlStore.delete(urlToken), this.URL_STORE_TTL);\n\n //Base64 encode callback url\n const callbackUrl = this.getBase64EncodedCallbackUrl();\n\n res.redirect(this.loginUrl + `?redirect_url=${callbackUrl}`);\n } catch (error) {\n console.error('Error in login middleware:', error);\n res.status(500).send('Internal server error');\n }\n }\n\n /**\n * logoutUser is a function that redirects the user to the Gneiss logout service.\n * It uses requireAuth to ensure the access token is valid before logout.\n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async logoutUser(req: Request, res: Response, next: NextFunction): Promise<void> {\n await this.requireAuth(req, res, async () => {\n const cookies = parseCookies(req);\n try {\n await this.logout(cookies?.accessToken);\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\"); // Redirect back to home after logout\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n console.error('Error in logout middleware:', error);\n res.status(500).send('Internal server error');\n }\n });\n }\n\n /**\n * Utility route handler for deleting a user.\n * This ensures that the user is fully logged out before\n * deleting the user's data.\n * \n * @param req - The request object.\n * @param res - The response object.\n * @param next - The next middleware function.\n */\n public async deleteUser(req: Request, res: Response, next: NextFunction): Promise<void> {\n await this.requireAuth(req, res, async () => {\n const cookies = parseCookies(req);\n try {\n await this.logout(cookies?.accessToken);\n clearCookies(res);\n await this.deleteUserData(cookies?.accessToken);\n res.redirect(\"/\");\n } catch (error) {\n if (error instanceof AxiosError) {\n switch (error.response?.status) {\n default:\n res\n .status(error.response?.status || 500)\n .send(error.response?.data || 'Internal server error');\n return;\n }\n }\n console.error('Error in deleteUser utility function:', error);\n res.status(500).send('Internal server error');\n }\n });\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["AxiosError", "config", "AxiosError"]
|
|
7
7
|
}
|
|
@@ -33,7 +33,7 @@ declare class ExpressAuthGneissClient extends AuthGneissCore {
|
|
|
33
33
|
* @param res - The response object.
|
|
34
34
|
* @param next - The next middleware function.
|
|
35
35
|
*/
|
|
36
|
-
getUser(req: Request, res: Response): Promise<void>;
|
|
36
|
+
getUser(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
37
37
|
/**
|
|
38
38
|
* handleCallBack is a middleware function that handles the callback from the authentication service.
|
|
39
39
|
* It extracts the auth code from the request URL parameters, exchanges it for tokens, and sets the access and refresh tokens in the response cookies.
|
|
@@ -52,19 +52,22 @@ declare class ExpressAuthGneissClient extends AuthGneissCore {
|
|
|
52
52
|
loginUser(req: Request, res: Response): void;
|
|
53
53
|
/**
|
|
54
54
|
* logoutUser is a function that redirects the user to the Gneiss logout service.
|
|
55
|
+
* It uses requireAuth to ensure the access token is valid before logout.
|
|
55
56
|
* @param req - The request object.
|
|
56
57
|
* @param res - The response object.
|
|
58
|
+
* @param next - The next middleware function.
|
|
57
59
|
*/
|
|
58
|
-
logoutUser(req: Request, res: Response): void
|
|
60
|
+
logoutUser(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
59
61
|
/**
|
|
60
|
-
* Utility route handler for deleting a user
|
|
62
|
+
* Utility route handler for deleting a user.
|
|
61
63
|
* This ensures that the user is fully logged out before
|
|
62
|
-
* deleting the user's data
|
|
64
|
+
* deleting the user's data.
|
|
63
65
|
*
|
|
64
66
|
* @param req - The request object.
|
|
65
67
|
* @param res - The response object.
|
|
68
|
+
* @param next - The next middleware function.
|
|
66
69
|
*/
|
|
67
|
-
deleteUser(req: Request, res: Response): void
|
|
70
|
+
deleteUser(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
68
71
|
}
|
|
69
72
|
export default ExpressAuthGneissClient;
|
|
70
73
|
//# sourceMappingURL=ExpressAuthGneissClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpressAuthGneissClient.d.ts","sourceRoot":"","sources":["../../../../../../src/frameworks/express/middleware/ExpressAuthGneissClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ1D;;;;;;;;;;;GAWG;AACH,cAAM,uBAAwB,SAAQ,cAAc;IAEhD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;gBAG5C,MAAM,EAAE,oBAAoB;IAkBhC;;;;;;;;;QASI;IACS,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpressAuthGneissClient.d.ts","sourceRoot":"","sources":["../../../../../../src/frameworks/express/middleware/ExpressAuthGneissClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ1D;;;;;;;;;;;GAWG;AACH,cAAM,uBAAwB,SAAQ,cAAc;IAEhD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;gBAG5C,MAAM,EAAE,oBAAoB;IAkBhC;;;;;;;;;QASI;IACS,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC/F;;;;;OAKG;IACU,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBpF;;;;;;OAMG;IACU,cAAc,CACvB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC;IA4ChB;;;;;;OAMG;IACI,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAgCnD;;;;;;OAMG;IACU,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBvF;;;;;;;;OAQG;IACU,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAuB1F;AAED,eAAe,uBAAuB,CAAC"}
|