@gneiss/client-auth 1.1.3 → 1.1.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.
@@ -54,9 +54,10 @@ var AuthGneissCore = class {
54
54
  constructor(devConfig) {
55
55
  this.config = { ...devConfig, ...config };
56
56
  this.authUrl = this.config.authUrl;
57
- this.loginUrl = this.authUrl ? `${this.authUrl}/auth/login` : void 0;
58
- this.logoutUrl = this.authUrl ? `${this.authUrl}/auth/logout` : void 0;
59
- this.signupUrl = this.authUrl ? `${this.authUrl}/auth/register` : void 0;
57
+ this.loginUrl = `${this.authUrl}/auth/login`;
58
+ this.logoutUrl = `${this.authUrl}/auth/logout`;
59
+ this.signupUrl = `${this.authUrl}/auth/register`;
60
+ this.callbackUrl = `${this.config.baseClientUrl}${this.config.callbackRoute}`;
60
61
  let errorMsgs = [];
61
62
  if (!process.env.ENV) {
62
63
  errorMsgs.push("ENV is not set in environment variables");
@@ -65,6 +66,9 @@ var AuthGneissCore = class {
65
66
  throw new Error(errorMsgs.join("\n"));
66
67
  }
67
68
  }
69
+ getBase64EncodedCallbackUrl() {
70
+ return Buffer.from(this.callbackUrl).toString("base64");
71
+ }
68
72
  /**
69
73
  * getTokens is a method that exchanges an authentication code for access and refresh tokens.
70
74
  * The client id and secret are passed as basic auth headers to authenticate the client itself.
@@ -230,6 +234,14 @@ function parseCookies(req) {
230
234
  return acc;
231
235
  }, {});
232
236
  }
237
+ function setUrlToken(res, stateToken, exp) {
238
+ res.cookie("urlToken", stateToken, {
239
+ httpOnly: true,
240
+ secure: process.env.ENV === "prod" || process.env.ENV === "staging",
241
+ sameSite: "lax",
242
+ maxAge: exp - Date.now()
243
+ });
244
+ }
233
245
  function clearCookies(res) {
234
246
  res.clearCookie("accessToken", {
235
247
  httpOnly: true,
@@ -243,14 +255,23 @@ function clearCookies(res) {
243
255
  sameSite: "strict",
244
256
  path: "/"
245
257
  });
258
+ res.clearCookie("urlToken", {
259
+ httpOnly: true,
260
+ secure: process.env.ENV === "prod" || process.env.ENV === "staging",
261
+ sameSite: "strict",
262
+ path: "/"
263
+ });
246
264
  }
247
265
 
248
266
  // src/frameworks/express/middleware/ExpressAuthGneissClient.ts
249
267
  var import_axios3 = require("axios");
250
268
  var import_axios4 = __toESM(require("axios"), 1);
251
269
  var ExpressAuthGneissClient = class extends AuthGneissCore_default {
270
+ // 10 minutes
252
271
  constructor(config2) {
253
272
  super(config2);
273
+ this.returnUrlStore = /* @__PURE__ */ new Map();
274
+ this.URL_STORE_TTL = 10 * 60 * 1e3;
254
275
  this.requireAuth = this.requireAuth.bind(this);
255
276
  this.handleCallBack = this.handleCallBack.bind(this);
256
277
  this.login = this.login.bind(this);
@@ -285,7 +306,7 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
285
306
  res.redirect(req.originalUrl);
286
307
  } else {
287
308
  const returnToUrl = req.originalUrl;
288
- res.redirect(`${this.loginUrl}?redirect_url=${this.config.baseClientUrl}${this.config.callbackUrl}&return_to_url=${returnToUrl}`);
309
+ res.redirect(`${this.loginUrl}?redirect_url=${this.getBase64EncodedCallbackUrl()}`);
289
310
  }
290
311
  } else {
291
312
  req.user = await this.getUserData(cookies.accessToken);
@@ -322,9 +343,11 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
322
343
  * @param next - The next middleware function.
323
344
  */
324
345
  async handleCallBack(req, res, next) {
346
+ const cookies = parseCookies(req);
347
+ const returnToToken = cookies?.urlToken;
325
348
  try {
326
349
  const authCode = req.query.auth_code;
327
- const returnToUrl = req.query.return_to_url;
350
+ const returnToUrl = this.returnUrlStore.get(returnToToken);
328
351
  if (!authCode) {
329
352
  throw new Error("No auth code found in request url parameters");
330
353
  }
@@ -356,7 +379,13 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
356
379
  if (!this.loginUrl) {
357
380
  throw new Error("Login URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.");
358
381
  }
359
- res.redirect(this.loginUrl + `?redirect_url=${this.config.baseClientUrl}${this.config.callbackUrl}`);
382
+ const returnToUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
383
+ const urlToken = crypto.randomUUID();
384
+ this.returnUrlStore.set(urlToken, returnToUrl);
385
+ setUrlToken(res, urlToken, this.URL_STORE_TTL);
386
+ setTimeout(() => this.returnUrlStore.delete(urlToken), this.URL_STORE_TTL);
387
+ const callbackUrl = this.getBase64EncodedCallbackUrl();
388
+ res.redirect(this.loginUrl + `?redirect_url=${callbackUrl}`);
360
389
  } catch (error) {
361
390
  console.error("Error in login middleware:", error);
362
391
  res.status(500).send("Internal server error");
@@ -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 generalConfig } 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 | undefined;\n protected loginUrl : string | undefined;\n protected logoutUrl : string | undefined;\n protected signupUrl : string | undefined;\n\n constructor(\n devConfig: AuthGneissCoreConfig\n ) {\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.loginUrl = this.authUrl ? `${this.authUrl}/auth/login` : undefined; // Login URL\n this.logoutUrl = this.authUrl ? `${this.authUrl}/auth/logout` : undefined; // Logout URL\n this.signupUrl = this.authUrl ? `${this.authUrl}/auth/register` : undefined; // Signup/register URL\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 /**\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.authUrl}/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.authUrl}/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 /**\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.authUrl}/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.authUrl}/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.authUrl}/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\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}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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\nfunction clearCookies(res: Response) {\n res.clearCookie(\"accessToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n res.clearCookie(\"refreshToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n}\n\nexport { setAccessToken, setRefreshToken, parseCookies, clearCookies };\n", "import { AuthGneissCore, AuthGneissCoreConfig } from \"@core\";\nimport { Request, Response, NextFunction } from \"express\";\nimport { AuthenticatedRequest, RequestWithTokens, Tokens } from \"@core/types\";\nimport { setAccessToken, setRefreshToken, parseCookies } from \"@utils\";\nimport { JwtPayload } from \"jsonwebtoken\";\nimport { AxiosError } from \"axios\";\nimport axios from \"axios\";\nimport { clearCookies } from \"@/utils/storage/cookieHandling\";\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 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.login = this.login.bind(this);\n this.logout = this.logout.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 redirect to the original requested url to 'redo' the request with new access token\n setAccessToken(res, newAccessToken);\n res.redirect(req.originalUrl)\n }\n else {\n // no access token or valid refresh token, redirect to login\n const returnToUrl : string | undefined = req.originalUrl as string;\n res.redirect(`${this.loginUrl}?redirect_url=${this.config.baseClientUrl}${this.config.callbackUrl}&return_to_url=${returnToUrl}`);\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 if (!accessToken) {\n throw new Error(\"No access token found in request cookies\");\n }\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\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 try {\n const authCode: string | undefined = req.query.auth_code as string\n const returnToUrl : string | undefined = req.query.return_to_url as string;\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 * @param req - The request object.\n * @param res - The response object.\n */\n public login(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 res.redirect(this.loginUrl + `?redirect_url=${this.config.baseClientUrl}${this.config.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 * logout 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 logout(req: Request, res: Response): void {\n const cookies = parseCookies(req);\n try {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n if (cookies?.accessToken) { // Only logout if the access token exists\n axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${cookies?.accessToken}`\n }\n });\n }\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\") // Redirect back to home after logout\n } catch (error) {\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 this.logout(req, res)\n this.deleteUserData(cookies?.accessToken)\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
5
- "mappings": "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",
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 generalConfig } 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\n constructor(\n devConfig: AuthGneissCoreConfig\n ) {\n\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.loginUrl = `${this.authUrl}/auth/login` // Login URL\n this.logoutUrl = `${this.authUrl}/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.authUrl}/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.authUrl}/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 /**\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.authUrl}/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.authUrl}/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.authUrl}/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\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}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\n maxAge: (exp) - Date.now()\n });\n}\n\nfunction clearCookies(res: Response) {\n res.clearCookie(\"accessToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n res.clearCookie(\"refreshToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n res.clearCookie(\"urlToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n\n });\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.login = this.login.bind(this);\n this.logout = this.logout.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 redirect to the original requested url to 'redo' the request with new access token\n setAccessToken(res, newAccessToken);\n res.redirect(req.originalUrl)\n }\n else {\n // no access token or valid refresh token, redirect to login\n const returnToUrl : string | undefined = req.originalUrl as string;\n res.redirect(`${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 if (!accessToken) {\n throw new Error(\"No access token found in request cookies\");\n }\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\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 * @param req - The request object.\n * @param res - The response object.\n */\n public login(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 const returnToUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\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 * logout 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 logout(req: Request, res: Response): void {\n const cookies = parseCookies(req);\n try {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n if (cookies?.accessToken) { // Only logout if the access token exists\n axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${cookies?.accessToken}`\n }\n });\n }\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\") // Redirect back to home after logout\n } catch (error) {\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 this.logout(req, res)\n this.deleteUserData(cookies?.accessToken)\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_axios", "dotenv", "axios", "import_axios", "config", "axios"]
7
7
  }
@@ -16,9 +16,10 @@ var AuthGneissCore = class {
16
16
  constructor(devConfig) {
17
17
  this.config = { ...devConfig, ...config };
18
18
  this.authUrl = this.config.authUrl;
19
- this.loginUrl = this.authUrl ? `${this.authUrl}/auth/login` : void 0;
20
- this.logoutUrl = this.authUrl ? `${this.authUrl}/auth/logout` : void 0;
21
- this.signupUrl = this.authUrl ? `${this.authUrl}/auth/register` : void 0;
19
+ this.loginUrl = `${this.authUrl}/auth/login`;
20
+ this.logoutUrl = `${this.authUrl}/auth/logout`;
21
+ this.signupUrl = `${this.authUrl}/auth/register`;
22
+ this.callbackUrl = `${this.config.baseClientUrl}${this.config.callbackRoute}`;
22
23
  let errorMsgs = [];
23
24
  if (!process.env.ENV) {
24
25
  errorMsgs.push("ENV is not set in environment variables");
@@ -27,6 +28,9 @@ var AuthGneissCore = class {
27
28
  throw new Error(errorMsgs.join("\n"));
28
29
  }
29
30
  }
31
+ getBase64EncodedCallbackUrl() {
32
+ return Buffer.from(this.callbackUrl).toString("base64");
33
+ }
30
34
  /**
31
35
  * getTokens is a method that exchanges an authentication code for access and refresh tokens.
32
36
  * The client id and secret are passed as basic auth headers to authenticate the client itself.
@@ -192,6 +196,14 @@ function parseCookies(req) {
192
196
  return acc;
193
197
  }, {});
194
198
  }
199
+ function setUrlToken(res, stateToken, exp) {
200
+ res.cookie("urlToken", stateToken, {
201
+ httpOnly: true,
202
+ secure: process.env.ENV === "prod" || process.env.ENV === "staging",
203
+ sameSite: "lax",
204
+ maxAge: exp - Date.now()
205
+ });
206
+ }
195
207
  function clearCookies(res) {
196
208
  res.clearCookie("accessToken", {
197
209
  httpOnly: true,
@@ -205,14 +217,23 @@ function clearCookies(res) {
205
217
  sameSite: "strict",
206
218
  path: "/"
207
219
  });
220
+ res.clearCookie("urlToken", {
221
+ httpOnly: true,
222
+ secure: process.env.ENV === "prod" || process.env.ENV === "staging",
223
+ sameSite: "strict",
224
+ path: "/"
225
+ });
208
226
  }
209
227
 
210
228
  // src/frameworks/express/middleware/ExpressAuthGneissClient.ts
211
229
  import { AxiosError as AxiosError2 } from "axios";
212
230
  import axios2 from "axios";
213
231
  var ExpressAuthGneissClient = class extends AuthGneissCore_default {
232
+ // 10 minutes
214
233
  constructor(config2) {
215
234
  super(config2);
235
+ this.returnUrlStore = /* @__PURE__ */ new Map();
236
+ this.URL_STORE_TTL = 10 * 60 * 1e3;
216
237
  this.requireAuth = this.requireAuth.bind(this);
217
238
  this.handleCallBack = this.handleCallBack.bind(this);
218
239
  this.login = this.login.bind(this);
@@ -247,7 +268,7 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
247
268
  res.redirect(req.originalUrl);
248
269
  } else {
249
270
  const returnToUrl = req.originalUrl;
250
- res.redirect(`${this.loginUrl}?redirect_url=${this.config.baseClientUrl}${this.config.callbackUrl}&return_to_url=${returnToUrl}`);
271
+ res.redirect(`${this.loginUrl}?redirect_url=${this.getBase64EncodedCallbackUrl()}`);
251
272
  }
252
273
  } else {
253
274
  req.user = await this.getUserData(cookies.accessToken);
@@ -284,9 +305,11 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
284
305
  * @param next - The next middleware function.
285
306
  */
286
307
  async handleCallBack(req, res, next) {
308
+ const cookies = parseCookies(req);
309
+ const returnToToken = cookies?.urlToken;
287
310
  try {
288
311
  const authCode = req.query.auth_code;
289
- const returnToUrl = req.query.return_to_url;
312
+ const returnToUrl = this.returnUrlStore.get(returnToToken);
290
313
  if (!authCode) {
291
314
  throw new Error("No auth code found in request url parameters");
292
315
  }
@@ -318,7 +341,13 @@ var ExpressAuthGneissClient = class extends AuthGneissCore_default {
318
341
  if (!this.loginUrl) {
319
342
  throw new Error("Login URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.");
320
343
  }
321
- res.redirect(this.loginUrl + `?redirect_url=${this.config.baseClientUrl}${this.config.callbackUrl}`);
344
+ const returnToUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
345
+ const urlToken = crypto.randomUUID();
346
+ this.returnUrlStore.set(urlToken, returnToUrl);
347
+ setUrlToken(res, urlToken, this.URL_STORE_TTL);
348
+ setTimeout(() => this.returnUrlStore.delete(urlToken), this.URL_STORE_TTL);
349
+ const callbackUrl = this.getBase64EncodedCallbackUrl();
350
+ res.redirect(this.loginUrl + `?redirect_url=${callbackUrl}`);
322
351
  } catch (error) {
323
352
  console.error("Error in login middleware:", error);
324
353
  res.status(500).send("Internal server error");
@@ -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 generalConfig } 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 | undefined;\n protected loginUrl : string | undefined;\n protected logoutUrl : string | undefined;\n protected signupUrl : string | undefined;\n\n constructor(\n devConfig: AuthGneissCoreConfig\n ) {\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.loginUrl = this.authUrl ? `${this.authUrl}/auth/login` : undefined; // Login URL\n this.logoutUrl = this.authUrl ? `${this.authUrl}/auth/logout` : undefined; // Logout URL\n this.signupUrl = this.authUrl ? `${this.authUrl}/auth/register` : undefined; // Signup/register URL\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 /**\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.authUrl}/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.authUrl}/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 /**\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.authUrl}/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.authUrl}/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.authUrl}/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\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}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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\nfunction clearCookies(res: Response) {\n res.clearCookie(\"accessToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n res.clearCookie(\"refreshToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n}\n\nexport { setAccessToken, setRefreshToken, parseCookies, clearCookies };\n", "import { AuthGneissCore, AuthGneissCoreConfig } from \"@core\";\nimport { Request, Response, NextFunction } from \"express\";\nimport { AuthenticatedRequest, RequestWithTokens, Tokens } from \"@core/types\";\nimport { setAccessToken, setRefreshToken, parseCookies } from \"@utils\";\nimport { JwtPayload } from \"jsonwebtoken\";\nimport { AxiosError } from \"axios\";\nimport axios from \"axios\";\nimport { clearCookies } from \"@/utils/storage/cookieHandling\";\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 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.login = this.login.bind(this);\n this.logout = this.logout.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 redirect to the original requested url to 'redo' the request with new access token\n setAccessToken(res, newAccessToken);\n res.redirect(req.originalUrl)\n }\n else {\n // no access token or valid refresh token, redirect to login\n const returnToUrl : string | undefined = req.originalUrl as string;\n res.redirect(`${this.loginUrl}?redirect_url=${this.config.baseClientUrl}${this.config.callbackUrl}&return_to_url=${returnToUrl}`);\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 if (!accessToken) {\n throw new Error(\"No access token found in request cookies\");\n }\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\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 try {\n const authCode: string | undefined = req.query.auth_code as string\n const returnToUrl : string | undefined = req.query.return_to_url as string;\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 * @param req - The request object.\n * @param res - The response object.\n */\n public login(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 res.redirect(this.loginUrl + `?redirect_url=${this.config.baseClientUrl}${this.config.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 * logout 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 logout(req: Request, res: Response): void {\n const cookies = parseCookies(req);\n try {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n if (cookies?.accessToken) { // Only logout if the access token exists\n axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${cookies?.accessToken}`\n }\n });\n }\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\") // Redirect back to home after logout\n } catch (error) {\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 this.logout(req, res)\n this.deleteUserData(cookies?.accessToken)\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
5
- "mappings": "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",
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 generalConfig } 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\n constructor(\n devConfig: AuthGneissCoreConfig\n ) {\n\n this.config = {...devConfig, ...generalConfig};\n this.authUrl = this.config.authUrl; // Gneiss endpoint\n this.loginUrl = `${this.authUrl}/auth/login` // Login URL\n this.logoutUrl = `${this.authUrl}/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.authUrl}/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.authUrl}/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 /**\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.authUrl}/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.authUrl}/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.authUrl}/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\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}", "import { Response } from \"express\";\nimport { JwtPayload, decode } from \"jsonwebtoken\";\nimport { Request } from \"express\";\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\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 httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'lax',\n maxAge: (exp) - Date.now()\n });\n}\n\nfunction clearCookies(res: Response) {\n res.clearCookie(\"accessToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n res.clearCookie(\"refreshToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n });\n res.clearCookie(\"urlToken\", {\n httpOnly: true,\n secure: process.env.ENV === 'prod' || process.env.ENV === 'staging',\n sameSite: 'strict',\n path: '/'\n\n });\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.login = this.login.bind(this);\n this.logout = this.logout.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 redirect to the original requested url to 'redo' the request with new access token\n setAccessToken(res, newAccessToken);\n res.redirect(req.originalUrl)\n }\n else {\n // no access token or valid refresh token, redirect to login\n const returnToUrl : string | undefined = req.originalUrl as string;\n res.redirect(`${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 if (!accessToken) {\n throw new Error(\"No access token found in request cookies\");\n }\n const userData = await this.getUserData(accessToken);\n res.status(200).send(userData);\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 * @param req - The request object.\n * @param res - The response object.\n */\n public login(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 const returnToUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\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 * logout 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 logout(req: Request, res: Response): void {\n const cookies = parseCookies(req);\n try {\n if (!this.logoutUrl) {\n throw new Error('Logout URL is not configured. Check if GNEISS_ENDPOINT environment variable is set.');\n }\n if (cookies?.accessToken) { // Only logout if the access token exists\n axios.post(this.logoutUrl, {}, { // Logout\n headers: {\n \"Authorization\": `Bearer ${cookies?.accessToken}`\n }\n });\n }\n clearCookies(res); // clear the access and refresh cookies\n res.redirect(\"/\") // Redirect back to home after logout\n } catch (error) {\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 this.logout(req, res)\n this.deleteUserData(cookies?.accessToken)\n }\n}\n\nexport default ExpressAuthGneissClient;\n"],
5
+ "mappings": "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",
6
6
  "names": ["AxiosError", "axios", "config", "AxiosError", "axios"]
7
7
  }
@@ -10,11 +10,13 @@ import { AuthGneissGeneralConfig } from "../config";
10
10
  */
11
11
  declare class AuthGneissCore {
12
12
  protected config: AuthGneissCoreConfig & AuthGneissGeneralConfig;
13
- protected authUrl: string | undefined;
14
- protected loginUrl: string | undefined;
15
- protected logoutUrl: string | undefined;
16
- protected signupUrl: string | undefined;
13
+ protected authUrl: string;
14
+ protected loginUrl: string;
15
+ protected logoutUrl: string;
16
+ protected signupUrl: string;
17
+ protected callbackUrl: string;
17
18
  constructor(devConfig: AuthGneissCoreConfig);
19
+ getBase64EncodedCallbackUrl(): string;
18
20
  /**
19
21
  * getTokens is a method that exchanges an authentication code for access and refresh tokens.
20
22
  * The client id and secret are passed as basic auth headers to authenticate the client itself.
@@ -1 +1 @@
1
- {"version":3,"file":"AuthGneissCore.d.ts","sourceRoot":"","sources":["../../../../src/core/AuthGneissCore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAOnD;;;;;;GAMG;AACH,cAAM,cAAc;IAChB,SAAS,CAAC,MAAM,EAAE,oBAAoB,GAAG,uBAAuB,CAAC;IACjE,SAAS,CAAC,OAAO,EAAG,MAAM,GAAG,SAAS,CAAC;IACvC,SAAS,CAAC,QAAQ,EAAG,MAAM,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,SAAS,EAAG,MAAM,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,SAAS,EAAG,MAAM,GAAG,SAAS,CAAC;gBAGrC,SAAS,EAAE,oBAAoB;IAkBnC;;;;;OAKG;cACa,SAAS,CAAC,QAAQ,EAAG,MAAM,GAAI,OAAO,CAAC,MAAM,CAAC;IAsB9D;;;;OAIG;cACa,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAe1E;;;;OAIG;IACU,WAAW,CAAC,WAAW,EAAE,MAAM;IAa5C;;;;OAIG;cACa,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAwB9D;;;OAGG;IACI,WAAW,IAAK,MAAM,GAAG,SAAS;IAIzC;;;OAGG;IACI,UAAU,IAAI,MAAM,GAAG,SAAS;IAIvC;;;OAGG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;IAIzC;;;OAGG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;IAIzC;;SAEK;cACW,cAAc,CAAC,WAAW,EAAG,MAAM,GAAI,OAAO,CAAC,MAAM,CAAC;CAQzE;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"AuthGneissCore.d.ts","sourceRoot":"","sources":["../../../../src/core/AuthGneissCore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAOnD;;;;;;GAMG;AACH,cAAM,cAAc;IAChB,SAAS,CAAC,MAAM,EAAE,oBAAoB,GAAG,uBAAuB,CAAC;IACjE,SAAS,CAAC,OAAO,EAAG,MAAM,CAAA;IAC1B,SAAS,CAAC,QAAQ,EAAG,MAAM,CAAA;IAC3B,SAAS,CAAC,SAAS,EAAG,MAAM,CAAA;IAC5B,SAAS,CAAC,SAAS,EAAG,MAAM,CAAA;IAC5B,SAAS,CAAC,WAAW,EAAG,MAAM,CAAA;gBAG1B,SAAS,EAAE,oBAAoB;IAoB5B,2BAA2B,IAAI,MAAM;IAI5C;;;;;OAKG;cACa,SAAS,CAAC,QAAQ,EAAG,MAAM,GAAI,OAAO,CAAC,MAAM,CAAC;IAsB9D;;;;OAIG;cACa,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAe1E;;;;OAIG;IACU,WAAW,CAAC,WAAW,EAAE,MAAM;IAa5C;;;;OAIG;cACa,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAwB9D;;;OAGG;IACI,WAAW,IAAK,MAAM,GAAG,SAAS;IAIzC;;;OAGG;IACI,UAAU,IAAI,MAAM,GAAG,SAAS;IAIvC;;;OAGG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;IAIzC;;;OAGG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;IAIzC;;SAEK;cACW,cAAc,CAAC,WAAW,EAAG,MAAM,GAAI,OAAO,CAAC,MAAM,CAAC;CAQzE;AAED,eAAe,cAAc,CAAC"}
@@ -3,7 +3,7 @@ interface AuthGneissCoreConfig {
3
3
  clientId: string;
4
4
  clientSecret: string;
5
5
  baseClientUrl: string;
6
- callbackUrl: string;
6
+ callbackRoute: string;
7
7
  }
8
8
  interface Tokens {
9
9
  accessToken: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,UAAU,oBAAoB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,MAAM;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,iBAAkB,SAAQ,OAAO;IACvC,OAAO,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACxB,CAAA;CACJ;AAED,UAAU,YAAY;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAEH,KAAK,oBAAoB,CAAC,KAAK,GAAG,YAAY,IAAI,OAAO,GAAG;IAC5D,IAAI,EAAE,KAAK,CAAC;CACX,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,UAAU,oBAAoB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,MAAM;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,iBAAkB,SAAQ,OAAO;IACvC,OAAO,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACxB,CAAA;CACJ;AAED,UAAU,YAAY;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAEH,KAAK,oBAAoB,CAAC,KAAK,GAAG,YAAY,IAAI,OAAO,GAAG;IAC5D,IAAI,EAAE,KAAK,CAAC;CACX,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
@@ -13,6 +13,8 @@ import { Request, Response, NextFunction } from "express";
13
13
  * });
14
14
  */
15
15
  declare class ExpressAuthGneissClient extends AuthGneissCore {
16
+ private returnUrlStore;
17
+ private readonly URL_STORE_TTL;
16
18
  constructor(config: AuthGneissCoreConfig);
17
19
  /**
18
20
  /**
@@ -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;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;IAkC/F;;;;;OAKG;IACU,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhE;;;;;;OAMG;IACU,cAAc,CACvB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC;IAkChB;;;;OAIG;IACI,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAY/C;;;;OAIG;IACI,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAqBhD;;;;;;;OAOG;IACI,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;CAKhD;AAED,eAAe,uBAAuB,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;IAkC/F;;;;;OAKG;IACU,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhE;;;;;;OAMG;IACU,cAAc,CACvB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC;IAuChB;;;;OAIG;IACI,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAwB/C;;;;OAIG;IACI,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAqBhD;;;;;;;OAOG;IACI,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;CAKhD;AAED,eAAe,uBAAuB,CAAC"}
@@ -1,2 +1,2 @@
1
- export { setAccessToken, setRefreshToken, parseCookies } from "./storage/cookieHandling";
1
+ export { setAccessToken, setRefreshToken, parseCookies, setUrlToken } from "./storage/cookieHandling";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC"}
@@ -15,6 +15,12 @@ declare function setRefreshToken(res: Response, refreshToken: string): void;
15
15
  declare function parseCookies(req: Request): {
16
16
  [key: string]: string;
17
17
  };
18
+ /**
19
+ * Set the state token in the response cookies.
20
+ * @param res - The response object.
21
+ * @param stateToken - The state token to set.
22
+ */
23
+ declare function setUrlToken(res: Response, stateToken: string, exp: number): void;
18
24
  declare function clearCookies(res: Response): void;
19
- export { setAccessToken, setRefreshToken, parseCookies, clearCookies };
25
+ export { setAccessToken, setRefreshToken, parseCookies, clearCookies, setUrlToken };
20
26
  //# sourceMappingURL=cookieHandling.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookieHandling.d.ts","sourceRoot":"","sources":["../../../../../src/utils/storage/cookieHandling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;GAIG;AACH,iBAAS,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,QAiBzD;AAED;;;;GAIG;AACH,iBAAS,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,QAc3D;AAED,iBAAS,YAAY,CAAC,GAAG,EAAE,OAAO,GAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAU9D;AAED,iBAAS,YAAY,CAAC,GAAG,EAAE,QAAQ,QAalC;AAED,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"cookieHandling.d.ts","sourceRoot":"","sources":["../../../../../src/utils/storage/cookieHandling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;GAIG;AACH,iBAAS,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,QAiBzD;AAED;;;;GAIG;AACH,iBAAS,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,QAc3D;AAED,iBAAS,YAAY,CAAC,GAAG,EAAE,OAAO,GAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAU9D;AAED;;;;GAIG;AACH,iBAAS,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QASlE;AAED,iBAAS,YAAY,CAAC,GAAG,EAAE,QAAQ,QAoBlC;AAED,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gneiss/client-auth",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "main": "dist/cjs/index.cjs",
5
5
  "module": "dist/esm/index.mjs",
6
6
  "types": "dist/types/src/index.d.ts",