@monocloud/auth-node-core 0.1.9 → 0.1.10

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/index.cjs CHANGED
@@ -268,6 +268,7 @@ const DEFAULT_OPTIONS = {
268
268
  responseType: "code"
269
269
  },
270
270
  allowQueryParamOverrides: true,
271
+ strictProfileSync: false,
271
272
  session: {
272
273
  cookie: {
273
274
  httpOnly: true,
@@ -403,6 +404,7 @@ const optionsSchema = joi.default.object({
403
404
  fetchUserInfo: boolRequired,
404
405
  refetchUserInfo: boolRequired,
405
406
  allowQueryParamOverrides: boolRequired,
407
+ strictProfileSync: boolRequired,
406
408
  defaultAuthParams: authParamSchema,
407
409
  resources: joi.default.array().items(indicatorOptionsSchema).optional(),
408
410
  session: sessionSchema,
@@ -445,6 +447,7 @@ const getTokensOptionsSchema = joi.default.object({
445
447
  resource: resourceValidationSchema.optional(),
446
448
  scopes: scopesValidationSchema.optional()
447
449
  });
450
+ const getSessionOptionsSchema = joi.default.object({ refetchUserInfo: boolOptional });
448
451
 
449
452
  //#endregion
450
453
  //#region src/options/get-options.ts
@@ -470,6 +473,7 @@ const getOptions = (options, throwOnError = true) => {
470
473
  const MONOCLOUD_AUTH_FETCH_USER_INFO = process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;
471
474
  const MONOCLOUD_AUTH_REFETCH_USER_INFO = process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;
472
475
  const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES = process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;
476
+ const MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC = process.env.MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC;
473
477
  const MONOCLOUD_AUTH_SESSION_COOKIE_NAME = process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;
474
478
  const MONOCLOUD_AUTH_SESSION_COOKIE_PATH = process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;
475
479
  const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN = process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;
@@ -519,6 +523,7 @@ const getOptions = (options, throwOnError = true) => {
519
523
  fetchUserInfo: (options === null || options === void 0 ? void 0 : options.fetchUserInfo) ?? (0, _monocloud_auth_core_internal.getBoolean)(MONOCLOUD_AUTH_FETCH_USER_INFO) ?? DEFAULT_OPTIONS.fetchUserInfo,
520
524
  refetchUserInfo: (options === null || options === void 0 ? void 0 : options.refetchUserInfo) ?? (0, _monocloud_auth_core_internal.getBoolean)(MONOCLOUD_AUTH_REFETCH_USER_INFO) ?? DEFAULT_OPTIONS.refetchUserInfo,
521
525
  allowQueryParamOverrides: (options === null || options === void 0 ? void 0 : options.allowQueryParamOverrides) ?? (0, _monocloud_auth_core_internal.getBoolean)(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ?? DEFAULT_OPTIONS.allowQueryParamOverrides,
526
+ strictProfileSync: (options === null || options === void 0 ? void 0 : options.strictProfileSync) ?? (0, _monocloud_auth_core_internal.getBoolean)(MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC) ?? DEFAULT_OPTIONS.strictProfileSync,
522
527
  session: {
523
528
  cookie: {
524
529
  name: (options === null || options === void 0 || (_options$session = options.session) === null || _options$session === void 0 || (_options$session = _options$session.cookie) === null || _options$session === void 0 ? void 0 : _options$session.name) ?? MONOCLOUD_AUTH_SESSION_COOKIE_NAME ?? DEFAULT_OPTIONS.session.cookie.name,
@@ -821,7 +826,10 @@ var MonoCloudCoreClient = class {
821
826
  response.sendJson(session.user);
822
827
  return response.done();
823
828
  }
824
- const newSession = await this.oidcClient.refetchUserInfo(defaultToken, session, { onSessionCreating: (_this$options$onSessi2 = this.options.onSessionCreating) === null || _this$options$onSessi2 === void 0 ? void 0 : _this$options$onSessi2.bind(this) });
829
+ const newSession = await this.oidcClient.refetchUserInfo(defaultToken, session, {
830
+ onSessionCreating: (_this$options$onSessi2 = this.options.onSessionCreating) === null || _this$options$onSessi2 === void 0 ? void 0 : _this$options$onSessi2.bind(this),
831
+ strictProfileSync: this.options.strictProfileSync
832
+ });
825
833
  if (!await this.sessionService.updateSession(request, response, newSession)) {
826
834
  response.setNoCache();
827
835
  response.noContent();
@@ -959,11 +967,26 @@ var MonoCloudCoreClient = class {
959
967
  *
960
968
  * @param request - MonoCloud cookie request object.
961
969
  * @param response - MonoCloud cookie response object.
970
+ * @param options - Optional configuration to control session retrieval behavior.
962
971
  *
963
972
  * @returns Session or `undefined`.
964
973
  */
965
- getSession(request, response) {
966
- return this.sessionService.getSession(request, response);
974
+ async getSession(request, response, options) {
975
+ var _this$options$onSessi3;
976
+ if (options) {
977
+ const { error } = getSessionOptionsSchema.validate(options, { abortEarly: true });
978
+ if (error) throw new _monocloud_auth_core.MonoCloudValidationError(error.details[0].message);
979
+ }
980
+ const session = await this.sessionService.getSession(request, response);
981
+ if (!(options === null || options === void 0 ? void 0 : options.refetchUserInfo) || !session) return session;
982
+ const defaultToken = (0, _monocloud_auth_core_internal.findToken)(session.accessTokens, this.options.defaultAuthParams.resource, session.authorizedScopes);
983
+ if (!defaultToken) throw new _monocloud_auth_core.MonoCloudValidationError("Access token not found");
984
+ const newSession = await this.oidcClient.refetchUserInfo(defaultToken, session, {
985
+ onSessionCreating: (_this$options$onSessi3 = this.options.onSessionCreating) === null || _this$options$onSessi3 === void 0 ? void 0 : _this$options$onSessi3.bind(this),
986
+ strictProfileSync: this.options.strictProfileSync
987
+ });
988
+ await this.sessionService.updateSession(request, response, newSession);
989
+ return newSession;
967
990
  }
968
991
  /**
969
992
  * Updates the current user's session with new data.
@@ -1030,7 +1053,7 @@ var MonoCloudCoreClient = class {
1030
1053
  let { idToken } = session;
1031
1054
  let { refreshToken } = session;
1032
1055
  if ((options === null || options === void 0 ? void 0 : options.forceRefresh) || !token || tokenExpired) {
1033
- var _this$options$onSessi3;
1056
+ var _this$options$onSessi4;
1034
1057
  if (!refreshToken && token && tokenExpired) throw new _monocloud_auth_core.MonoCloudTokenError("No refresh token available to refresh the expired access token");
1035
1058
  const updatedSession = await this.oidcClient.refreshSession(session, {
1036
1059
  fetchUserInfo: (options === null || options === void 0 ? void 0 : options.refetchUserInfo) ?? this.options.refetchUserInfo,
@@ -1042,7 +1065,8 @@ var MonoCloudCoreClient = class {
1042
1065
  scopes
1043
1066
  },
1044
1067
  filteredIdTokenClaims: this.options.filteredIdTokenClaims,
1045
- onSessionCreating: (_this$options$onSessi3 = this.options.onSessionCreating) === null || _this$options$onSessi3 === void 0 ? void 0 : _this$options$onSessi3.bind(this)
1068
+ onSessionCreating: (_this$options$onSessi4 = this.options.onSessionCreating) === null || _this$options$onSessi4 === void 0 ? void 0 : _this$options$onSessi4.bind(this),
1069
+ strictProfileSync: this.options.strictProfileSync
1046
1070
  });
1047
1071
  await this.sessionService.updateSession(request, response, updatedSession);
1048
1072
  token = (0, _monocloud_auth_core_internal.findToken)(updatedSession === null || updatedSession === void 0 ? void 0 : updatedSession.accessTokens, resource, findTokenScopes);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["cookie","Joi","MonoCloudValidationError","MonoCloudOidcClient","MonoCloudValidationError","MonoCloudOPError","MonoCloudTokenError"],"sources":["../src/monocloud-session-service.ts","../src/monocloud-state-service.ts","../src/options/defaults.ts","../src/options/validation.ts","../src/options/get-options.ts","../src/monocloud-node-core-client.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid';\nimport { serialize } from 'cookie';\nimport { decrypt, encrypt } from '@monocloud/auth-core/utils';\nimport type { MonoCloudSession, MonoCloudUser } from '@monocloud/auth-core';\nimport { now } from '@monocloud/auth-core/internal';\nimport { MonoCloudOptionsBase } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n SessionCookieValue,\n} from './types/internal';\n\nconst CHUNK_BYTE_SIZE = 4090;\n\nexport class MonoCloudSessionService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<string> {\n // Generate a session Id\n const key = uuid();\n\n // Set the issued and updated time\n const iat = now();\n const uat = iat;\n\n // Calculate the lifetime of the cookie\n const exp = this.getExpiry(iat, uat);\n\n // Set the Cookie Value\n const cookieValue: SessionCookieValue = {\n key,\n lifetime: { c: iat, u: uat, e: exp },\n };\n\n // Save the Session\n await this.saveSession(req, res, cookieValue, session);\n\n // Return the session Id\n return key;\n }\n\n async getSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n shouldResave = true\n ): Promise<MonoCloudSession | undefined> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return undefined;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // if there is no session store\n if (!this.options.session.store) {\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n\n // ensure that the cookie has a session\n if (!cookieValue.session) {\n return undefined;\n }\n\n // create a session object\n Object.assign(session, JSON.parse(JSON.stringify(cookieValue.session)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n // Get the session from the store\n const sessionObj = await this.options.session.store.get(cookieValue.key);\n\n // if there is no session in the store then delete the cookie\n if (!sessionObj) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Get the instance of the session\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n Object.assign(session, JSON.parse(JSON.stringify(sessionObj)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n async updateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<boolean> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return false;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return false;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // Save the session\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n\n return true;\n }\n\n async removeSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Delete the current session from the store\n /* v8 ignore else -- @preserve */\n if (cookieValue.key) {\n await this.options.session.store.delete(cookieValue.key);\n }\n }\n\n await this.deleteAllCookies(req, res);\n }\n\n private async validateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue\n ): Promise<boolean> {\n // Get the current time\n const nowTime = now();\n\n let isValid = true;\n\n // Ensure that the expiration has not passed\n if (cookieValue.lifetime.e && cookieValue.lifetime.e < nowTime) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not expired based on the last updated time\n if (\n this.options.session.sliding &&\n cookieValue.lifetime.u + this.options.session.duration < nowTime\n ) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not crossed the maximum duration allowed\n if (\n cookieValue.lifetime.c + this.options.session.maximumDuration <\n nowTime\n ) {\n isValid = false;\n }\n\n // return Is Valid if all ok\n if (isValid) {\n return true;\n }\n\n // If there is a session store then delete the session from the store\n if (this.options.session.store) {\n await this.options.session.store.delete(cookieValue.key);\n }\n\n await this.deleteAllCookies(req, res);\n\n return false;\n }\n\n private async saveSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue,\n session: MonoCloudSession\n ): Promise<void> {\n const cookies = new Set((await this.getRequestCookie(req))?.keys ?? []);\n\n // If no session store is present\n if (!this.options.session.store) {\n // Set the cookie session Value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = session;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Get the cookie containing the session Id\n const cookieData = await this.getCookieData(req);\n\n // Delete the current session from the store\n if (cookieData?.key) {\n await this.options.session.store.delete(cookieData.key);\n }\n\n // Ensure there is no session in the cookie value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = undefined;\n\n // Set the new session in the store\n await this.options.session.store.set(\n cookieValue.key,\n session,\n cookieValue.lifetime\n );\n }\n\n // Encrypt the cookie value\n const encryptedData = await encrypt(\n JSON.stringify(cookieValue),\n this.options.cookieSecret\n );\n\n const cookieExpiry = cookieValue.lifetime.e\n ? new Date(cookieValue.lifetime.e * 1000)\n : undefined;\n\n const cookieOptions = this.getCookieOptions(cookieExpiry);\n const chunkSize =\n CHUNK_BYTE_SIZE -\n serialize(`${this.options.session.cookie.name}.0`, '', cookieOptions)\n .length;\n\n // Calculate the number of cookie chunks\n const chunks = Math.ceil(encryptedData.length / chunkSize);\n\n for (let i = 0; i < chunks; i += 1) {\n const encryptedChunk = encryptedData.slice(\n i * chunkSize,\n (i + 1) * chunkSize\n );\n\n const cookieName =\n chunks === 1\n ? this.options.session.cookie.name\n : `${this.options.session.cookie.name}.${i}`;\n\n await res.setCookie(\n cookieName,\n encryptedChunk,\n this.getCookieOptions(cookieExpiry)\n );\n\n cookies.delete(cookieName);\n }\n\n // Delete all cookies which are not required anymore\n for (const cookie of cookies) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n\n private async getCookieData(\n req: IMonoCloudCookieRequest\n ): Promise<SessionCookieValue | undefined> {\n // Get all the cookies\n const cookieData = await this.getRequestCookie(req);\n\n // Handle no cookies\n if (!cookieData?.value) {\n return undefined;\n }\n\n // Decrypt the cookie\n const data = await decrypt(cookieData.value, this.options.cookieSecret);\n\n // Handle no data\n if (!data) {\n return undefined;\n }\n\n // Return the parsed session cookie value\n return JSON.parse(data);\n }\n\n private async getRequestCookie(\n req: IMonoCloudCookieRequest\n ): Promise<{ keys: string[]; value: string } | undefined> {\n // Get all the cookies\n const cookies = await req.getAllCookies();\n\n // Handle no cookies\n if (!cookies.size) {\n return undefined;\n }\n\n // If a cookie exists without chunks then return it\n const val = cookies.get(this.options.session.cookie.name);\n\n if (val) {\n return { keys: [this.options.session.cookie.name], value: val };\n }\n\n // Filter out the cookies and only keep the relevant ones\n const cookieValues = Array.from(cookies.entries())\n .filter(([cookie]) =>\n cookie.startsWith(`${this.options.session.cookie.name}.`)\n )\n .map(([cookie, value]) => ({\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n key: parseInt(cookie.split('.').pop() || '0', 10),\n value,\n }))\n .sort((a, b) => a.key - b.key);\n\n // Sort the cookies by chunk numbers\n const cookieValue = cookieValues.map(({ value }) => value).join('');\n\n // Handle empty cookie value\n if (!cookieValue) {\n return undefined;\n }\n\n // Return the cookie names and values\n return {\n keys: cookieValues.map(\n ({ key }) => `${this.options.session.cookie.name}.${key}`\n ),\n value: cookieValue,\n };\n }\n\n private getExpiry(iat: number, uat: number): number | undefined {\n // Return null if session is not persistent\n if (!this.options.session.cookie.persistent) {\n return undefined;\n }\n\n // If session is not sliding the return the absolute expiration\n if (!this.options.session.sliding) {\n return Math.floor(iat + this.options.session.duration);\n }\n\n // If session is sliding then return the lesser of the next extended time or the maximum duration\n return Math.floor(\n Math.min(\n uat + this.options.session.duration,\n iat + this.options.session.maximumDuration\n )\n );\n }\n\n private getCookieOptions(exp?: Date): CookieOptions {\n return {\n domain: this.options.session.cookie.domain,\n httpOnly: this.options.session.cookie.httpOnly,\n sameSite: this.options.session.cookie.sameSite,\n secure: this.options.session.cookie.secure,\n path: this.options.session.cookie.path,\n expires: exp,\n };\n }\n\n private async deleteAllCookies(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n const reqCookie = await this.getRequestCookie(req);\n\n const cookies = reqCookie?.keys?.filter(x =>\n x.startsWith(this.options.session.cookie.name)\n );\n\n for (const cookie of cookies ?? []) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n}\n","import { decryptAuthState, encryptAuthState } from '@monocloud/auth-core/utils';\nimport { MonoCloudOptionsBase, MonoCloudState, SameSiteValues } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n} from './types/internal';\n\nexport class MonoCloudStateService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setState(\n res: IMonoCloudCookieResponse,\n state: MonoCloudState,\n overrideSameSite?: SameSiteValues\n ): Promise<void> {\n await res.setCookie(\n this.options.state.cookie.name,\n await encryptAuthState(state, this.options.cookieSecret),\n this.getCookieOptions(overrideSameSite)\n );\n }\n\n async getState(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<MonoCloudState | undefined> {\n // Get the cookie\n const cookie = await req.getCookie(this.options.state.cookie.name);\n\n // Handle no cookie\n if (!cookie) {\n return undefined;\n }\n\n let decryptedResult: MonoCloudState;\n\n try {\n // Decrypt the cookie value\n decryptedResult = await decryptAuthState(\n cookie,\n this.options.cookieSecret\n );\n } catch {\n return undefined;\n }\n\n // Remove the cookie\n await res.setCookie(this.options.state.cookie.name, '', {\n ...this.getCookieOptions(),\n expires: new Date(0),\n });\n\n // return the state\n return decryptedResult;\n }\n\n private getCookieOptions(sameSite?: SameSiteValues): CookieOptions {\n return {\n domain: this.options.state.cookie.domain,\n httpOnly: this.options.state.cookie.httpOnly,\n sameSite: sameSite ?? this.options.state.cookie.sameSite,\n secure: this.options.state.cookie.secure,\n path: this.options.state.cookie.path,\n };\n }\n}\n","export const DEFAULT_OPTIONS = {\n routes: {\n callback: '/api/auth/callback',\n backChannelLogout: '/api/auth/backchannel-logout',\n signIn: '/api/auth/signin',\n signOut: '/api/auth/signout',\n userInfo: '/api/auth/userinfo',\n },\n clockSkew: 60,\n responseTimeout: 10000,\n usePar: false,\n fetchUserInfo: true,\n refetchUserInfo: false,\n federatedSignOut: true,\n defaultAuthParams: {\n scopes: 'openid profile email',\n responseType: 'code',\n },\n allowQueryParamOverrides: true,\n session: {\n cookie: {\n httpOnly: true,\n name: 'session',\n path: '/',\n sameSite: 'lax',\n persistent: true,\n },\n sliding: false,\n duration: 24 * 60 * 60,\n maximumDuration: 7 * 24 * 60 * 60,\n },\n state: {\n cookie: {\n httpOnly: true,\n name: 'state',\n path: '/',\n sameSite: 'lax',\n persistent: false,\n },\n },\n idTokenSigningAlg: 'RS256',\n filteredIdTokenClaims: [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n ],\n debugger: 'node-auth-core',\n userAgent: 'node-auth-core',\n};\n","import Joi from 'joi';\nimport type { AuthorizationParams } from '@monocloud/auth-core';\nimport {\n CallbackOptions,\n GetTokensOptions,\n Indicator,\n MonoCloudOptionsBase,\n MonoCloudRoutes,\n MonoCloudSessionOptionsBase,\n MonoCloudStateOptions,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from '../types';\n\nconst stringRequired = Joi.string().required();\nconst stringOptional = Joi.string().optional();\nconst boolRequired = Joi.boolean().required();\nconst boolOptional = Joi.boolean().optional();\nconst numRequired = Joi.number().required();\nconst numOptional = Joi.number().optional();\nconst objectOptional = Joi.object().optional();\nconst funcOptional = Joi.function().optional();\n\nconst sessionCookieSchema = Joi.object({\n name: stringRequired,\n path: stringRequired.uri({ relativeOnly: true }),\n domain: stringOptional,\n httpOnly: boolRequired,\n secure: boolRequired.when(Joi.ref('/appUrl'), {\n is: Joi.string().pattern(/^https:/i),\n then: Joi.valid(true).messages({\n 'any.only':\n 'Cookie must be set to secure when app url protocol is https.',\n }),\n otherwise: Joi.valid(false),\n }),\n sameSite: stringRequired.valid('strict', 'lax', 'none'),\n persistent: boolRequired,\n}).required();\n\nconst resourceSchema = stringRequired.custom((value, helpers) => {\n let valid: boolean;\n try {\n const url = new URL(value);\n valid = url.searchParams.size === 0 && url.hash.length === 0;\n } catch {\n valid = false;\n }\n\n if (!valid) {\n return helpers.message({\n custom: 'Resource must be a valid URL without query or hash parameters',\n });\n }\n\n return value;\n});\n\nexport const resourceValidationSchema = Joi.string()\n .custom((value, helpers) => {\n const parts = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (parts.length === 0) {\n return helpers.message({ custom: 'Resource must not be empty' });\n }\n\n for (const part of parts) {\n const { error } = resourceSchema.validate(part);\n if (error) {\n return helpers.message({\n custom: `Invalid resource \"${part}\": ${error.message}`,\n });\n }\n }\n\n return parts.join(' ');\n })\n .messages({\n 'string.base': 'Resource must be a space-separated string of URLs',\n });\n\nconst sessionSchema: Joi.ObjectSchema<MonoCloudSessionOptionsBase> = Joi.object(\n {\n cookie: sessionCookieSchema,\n sliding: boolRequired,\n duration: numRequired.min(1),\n maximumDuration: numRequired.min(1).greater(Joi.ref('duration')),\n store: objectOptional,\n }\n).required();\n\nconst stateSchema: Joi.ObjectSchema<MonoCloudStateOptions> = Joi.object({\n cookie: sessionCookieSchema,\n}).required();\n\nconst scopesSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n if (!scopes.includes('openid')) {\n return helpers.message({ custom: 'Scope must contain openid' });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nconst authParamSchema: Joi.ObjectSchema<AuthorizationParams> = Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n resource: resourceValidationSchema.optional(),\n})\n .unknown(true)\n .required();\n\nconst optionalAuthParamSchema: Joi.ObjectSchema<AuthorizationParams> =\n Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n })\n .unknown(true)\n .optional();\n\nconst routesSchema: Joi.ObjectSchema<MonoCloudRoutes> = Joi.object({\n callback: stringRequired.uri({ relativeOnly: true }),\n backChannelLogout: stringRequired.uri({ relativeOnly: true }),\n signIn: stringRequired.uri({ relativeOnly: true }),\n signOut: stringRequired.uri({ relativeOnly: true }),\n userInfo: stringRequired.uri({ relativeOnly: true }),\n}).required();\n\nexport const scopesValidationSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nexport const indicatorOptionsSchema: Joi.ObjectSchema<Indicator> = Joi.object({\n resource: resourceValidationSchema,\n scopes: scopesValidationSchema.optional(),\n});\n\nexport const optionsSchema: Joi.ObjectSchema<MonoCloudOptionsBase> = Joi.object(\n {\n clientId: stringRequired,\n clientSecret: stringRequired,\n tenantDomain: stringRequired.uri(),\n cookieSecret: stringRequired.min(8),\n appUrl: stringRequired.uri(),\n routes: routesSchema,\n clockSkew: numRequired,\n responseTimeout: numRequired.min(1000),\n usePar: boolRequired,\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n federatedSignOut: boolRequired,\n fetchUserInfo: boolRequired,\n refetchUserInfo: boolRequired,\n allowQueryParamOverrides: boolRequired,\n defaultAuthParams: authParamSchema,\n resources: Joi.array<Indicator>().items(indicatorOptionsSchema).optional(),\n session: sessionSchema,\n state: stateSchema,\n idTokenSigningAlg: Joi.string().valid(\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512'\n ),\n filteredIdTokenClaims: Joi.array<string>().items(stringRequired),\n debugger: stringRequired,\n userAgent: stringRequired,\n jwksCacheDuration: numOptional,\n metadataCacheDuration: numOptional,\n onBackChannelLogout: funcOptional,\n onSetApplicationState: funcOptional,\n onSessionCreating: funcOptional,\n }\n);\n\nexport const signInOptionsSchema: Joi.ObjectSchema<SignInOptions> = Joi.object({\n returnUrl: stringOptional.uri({ allowRelative: true }),\n register: boolOptional,\n authParams: optionalAuthParamSchema,\n onError: funcOptional,\n});\n\nexport const callbackOptionsSchema: Joi.ObjectSchema<CallbackOptions> =\n Joi.object({\n fetchUserInfo: boolOptional,\n redirectUri: stringOptional.uri(),\n onError: funcOptional,\n });\n\nexport const userInfoOptionsSchema: Joi.ObjectSchema<UserInfoOptions> =\n Joi.object({\n refresh: boolOptional,\n onError: funcOptional,\n });\n\nexport const signOutOptionsSchema: Joi.ObjectSchema<SignOutOptions> =\n Joi.object({\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n idToken: stringOptional,\n state: stringOptional,\n federatedSignOut: boolOptional,\n onError: funcOptional,\n });\n\nexport const getTokensOptionsSchema: Joi.ObjectSchema<GetTokensOptions> =\n Joi.object({\n forceRefresh: boolOptional,\n refetchUserInfo: boolOptional,\n resource: resourceValidationSchema.optional(),\n scopes: scopesValidationSchema.optional(),\n });\n","/* eslint-disable prefer-destructuring */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {\n getBoolean,\n getNumber,\n removeTrailingSlash,\n} from '@monocloud/auth-core/internal';\nimport {\n MonoCloudOptions,\n MonoCloudOptionsBase,\n SameSiteValues,\n} from '../types';\nimport { DEFAULT_OPTIONS } from './defaults';\nimport { optionsSchema } from './validation';\nimport {\n MonoCloudValidationError,\n SecurityAlgorithms,\n} from '@monocloud/auth-core';\n\nexport const getOptions = (\n options?: MonoCloudOptions,\n throwOnError = true\n): MonoCloudOptionsBase => {\n const MONOCLOUD_AUTH_CLIENT_ID = process.env.MONOCLOUD_AUTH_CLIENT_ID;\n const MONOCLOUD_AUTH_CLIENT_SECRET = process.env.MONOCLOUD_AUTH_CLIENT_SECRET;\n const MONOCLOUD_AUTH_TENANT_DOMAIN = process.env.MONOCLOUD_AUTH_TENANT_DOMAIN;\n const MONOCLOUD_AUTH_SCOPES = process.env.MONOCLOUD_AUTH_SCOPES;\n const MONOCLOUD_AUTH_COOKIE_SECRET = process.env.MONOCLOUD_AUTH_COOKIE_SECRET;\n const MONOCLOUD_AUTH_APP_URL = process.env.MONOCLOUD_AUTH_APP_URL;\n const MONOCLOUD_AUTH_CALLBACK_URL = process.env.MONOCLOUD_AUTH_CALLBACK_URL;\n const MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL =\n process.env.MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL;\n const MONOCLOUD_AUTH_SIGNIN_URL = process.env.MONOCLOUD_AUTH_SIGNIN_URL;\n const MONOCLOUD_AUTH_SIGNOUT_URL = process.env.MONOCLOUD_AUTH_SIGNOUT_URL;\n const MONOCLOUD_AUTH_USER_INFO_URL = process.env.MONOCLOUD_AUTH_USER_INFO_URL;\n const MONOCLOUD_AUTH_RESOURCE = process.env.MONOCLOUD_AUTH_RESOURCE;\n const MONOCLOUD_AUTH_CLOCK_SKEW = process.env.MONOCLOUD_AUTH_CLOCK_SKEW;\n const MONOCLOUD_AUTH_RESPONSE_TIMEOUT =\n process.env.MONOCLOUD_AUTH_RESPONSE_TIMEOUT;\n const MONOCLOUD_AUTH_USE_PAR = process.env.MONOCLOUD_AUTH_USE_PAR;\n const MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI =\n process.env.MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI;\n const MONOCLOUD_AUTH_FEDERATED_SIGNOUT =\n process.env.MONOCLOUD_AUTH_FEDERATED_SIGNOUT;\n const MONOCLOUD_AUTH_FETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;\n const MONOCLOUD_AUTH_REFETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;\n const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES =\n process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;\n const MONOCLOUD_AUTH_SESSION_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;\n const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SECURE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_SESSION_SLIDING =\n process.env.MONOCLOUD_AUTH_SESSION_SLIDING;\n const MONOCLOUD_AUTH_SESSION_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_DURATION;\n const MONOCLOUD_AUTH_SESSION_MAX_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_MAX_DURATION;\n const MONOCLOUD_AUTH_STATE_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_NAME;\n const MONOCLOUD_AUTH_STATE_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PATH;\n const MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_STATE_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SECURE;\n const MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG =\n process.env.MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG;\n const MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS =\n process.env.MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS;\n const MONOCLOUD_AUTH_JWKS_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_JWKS_CACHE_DURATION;\n const MONOCLOUD_AUTH_METADATA_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_METADATA_CACHE_DURATION;\n\n const appUrl = options?.appUrl ?? MONOCLOUD_AUTH_APP_URL!;\n\n const opt: MonoCloudOptionsBase = {\n clientId: options?.clientId ?? MONOCLOUD_AUTH_CLIENT_ID!,\n clientSecret: options?.clientSecret ?? MONOCLOUD_AUTH_CLIENT_SECRET,\n tenantDomain: options?.tenantDomain ?? MONOCLOUD_AUTH_TENANT_DOMAIN!,\n defaultAuthParams: {\n ...(options?.defaultAuthParams ?? {}),\n scopes:\n options?.defaultAuthParams?.scopes ??\n MONOCLOUD_AUTH_SCOPES ??\n DEFAULT_OPTIONS.defaultAuthParams.scopes,\n responseType:\n options?.defaultAuthParams?.responseType ??\n (DEFAULT_OPTIONS.defaultAuthParams.responseType as any),\n resource: options?.defaultAuthParams?.resource ?? MONOCLOUD_AUTH_RESOURCE,\n },\n resources: options?.resources,\n cookieSecret: options?.cookieSecret ?? MONOCLOUD_AUTH_COOKIE_SECRET!,\n appUrl: removeTrailingSlash(appUrl),\n routes: {\n callback: removeTrailingSlash(\n options?.routes?.callback ??\n MONOCLOUD_AUTH_CALLBACK_URL ??\n DEFAULT_OPTIONS.routes.callback\n ),\n backChannelLogout: removeTrailingSlash(\n options?.routes?.backChannelLogout ??\n MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL ??\n DEFAULT_OPTIONS.routes.backChannelLogout\n ),\n signIn: removeTrailingSlash(\n options?.routes?.signIn ??\n MONOCLOUD_AUTH_SIGNIN_URL ??\n DEFAULT_OPTIONS.routes.signIn\n ),\n signOut: removeTrailingSlash(\n options?.routes?.signOut ??\n MONOCLOUD_AUTH_SIGNOUT_URL ??\n DEFAULT_OPTIONS.routes.signOut\n ),\n userInfo: removeTrailingSlash(\n options?.routes?.userInfo ??\n MONOCLOUD_AUTH_USER_INFO_URL ??\n DEFAULT_OPTIONS.routes.userInfo\n ),\n },\n clockSkew:\n options?.clockSkew ??\n getNumber(MONOCLOUD_AUTH_CLOCK_SKEW) ??\n DEFAULT_OPTIONS.clockSkew,\n responseTimeout:\n options?.responseTimeout ??\n getNumber(MONOCLOUD_AUTH_RESPONSE_TIMEOUT) ??\n DEFAULT_OPTIONS.responseTimeout,\n usePar:\n options?.usePar ??\n getBoolean(MONOCLOUD_AUTH_USE_PAR) ??\n DEFAULT_OPTIONS.usePar,\n postLogoutRedirectUri:\n options?.postLogoutRedirectUri ?? MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI,\n federatedSignOut:\n options?.federatedSignOut ??\n getBoolean(MONOCLOUD_AUTH_FEDERATED_SIGNOUT) ??\n DEFAULT_OPTIONS.federatedSignOut,\n fetchUserInfo:\n options?.fetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_FETCH_USER_INFO) ??\n DEFAULT_OPTIONS.fetchUserInfo,\n refetchUserInfo:\n options?.refetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_REFETCH_USER_INFO) ??\n DEFAULT_OPTIONS.refetchUserInfo,\n allowQueryParamOverrides:\n options?.allowQueryParamOverrides ??\n getBoolean(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ??\n DEFAULT_OPTIONS.allowQueryParamOverrides,\n session: {\n cookie: {\n name:\n options?.session?.cookie?.name ??\n MONOCLOUD_AUTH_SESSION_COOKIE_NAME ??\n DEFAULT_OPTIONS.session.cookie.name,\n path:\n options?.session?.cookie?.path ??\n MONOCLOUD_AUTH_SESSION_COOKIE_PATH ??\n DEFAULT_OPTIONS.session.cookie.path,\n domain:\n options?.session?.cookie?.domain ??\n MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN,\n httpOnly:\n options?.session?.cookie?.httpOnly ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY) ??\n DEFAULT_OPTIONS.session.cookie.httpOnly,\n secure:\n options?.session?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.session?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.session.cookie.sameSite,\n persistent:\n options?.session?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.session.cookie.persistent,\n },\n sliding:\n options?.session?.sliding ??\n getBoolean(MONOCLOUD_AUTH_SESSION_SLIDING) ??\n DEFAULT_OPTIONS.session.sliding,\n duration:\n options?.session?.duration ??\n getNumber(MONOCLOUD_AUTH_SESSION_DURATION) ??\n DEFAULT_OPTIONS.session.duration,\n maximumDuration:\n options?.session?.maximumDuration ??\n getNumber(MONOCLOUD_AUTH_SESSION_MAX_DURATION) ??\n DEFAULT_OPTIONS.session.maximumDuration,\n store: options?.session?.store,\n },\n state: {\n cookie: {\n name:\n options?.state?.cookie?.name ??\n MONOCLOUD_AUTH_STATE_COOKIE_NAME ??\n DEFAULT_OPTIONS.state.cookie.name,\n path:\n options?.state?.cookie?.path ??\n MONOCLOUD_AUTH_STATE_COOKIE_PATH ??\n DEFAULT_OPTIONS.state.cookie.path,\n domain:\n options?.state?.cookie?.domain ?? MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN,\n httpOnly: DEFAULT_OPTIONS.state.cookie.httpOnly,\n secure:\n options?.state?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.state?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.state.cookie.sameSite,\n persistent:\n options?.state?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.state.cookie.persistent,\n },\n },\n idTokenSigningAlg:\n options?.idTokenSigningAlg ??\n (MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG as SecurityAlgorithms) ??\n DEFAULT_OPTIONS.idTokenSigningAlg,\n filteredIdTokenClaims:\n options?.filteredIdTokenClaims ??\n MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS?.split(' ')\n .map(x => x.trim())\n .filter(x => x.length) ??\n DEFAULT_OPTIONS.filteredIdTokenClaims,\n debugger: options?.debugger ?? DEFAULT_OPTIONS.debugger,\n userAgent: options?.userAgent ?? DEFAULT_OPTIONS.userAgent,\n jwksCacheDuration:\n options?.jwksCacheDuration ??\n getNumber(MONOCLOUD_AUTH_JWKS_CACHE_DURATION),\n metadataCacheDuration:\n options?.metadataCacheDuration ??\n getNumber(MONOCLOUD_AUTH_METADATA_CACHE_DURATION),\n onBackChannelLogout: options?.onBackChannelLogout,\n onSetApplicationState: options?.onSetApplicationState,\n onSessionCreating: options?.onSessionCreating,\n };\n\n const { value, error } = optionsSchema.validate(opt, { abortEarly: false });\n\n const requiredEnv: Record<string, string> = {\n tenantDomain: 'MONOCLOUD_AUTH_TENANT_DOMAIN',\n clientId: 'MONOCLOUD_AUTH_CLIENT_ID',\n clientSecret: 'MONOCLOUD_AUTH_CLIENT_SECRET',\n appUrl: 'MONOCLOUD_AUTH_APP_URL',\n cookieSecret: 'MONOCLOUD_AUTH_COOKIE_SECRET',\n };\n\n if (error) {\n if (throwOnError) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n 'WARNING: One or more configuration options were not provided for MonoCloudClient.'\n );\n error.details.forEach(detail => {\n if (detail.context?.key && requiredEnv[detail.context.key]) {\n // eslint-disable-next-line no-console\n console.warn(\n `Missing: ${detail.context.key} - Set ${requiredEnv[detail.context.key]} environment variable in your .env file.`\n );\n }\n });\n }\n\n return value;\n};\n","import { createRemoteJWKSet, JWTPayload, jwtVerify } from 'jose';\nimport {\n ensureLeadingSlash,\n findToken,\n getBoolean,\n isAbsoluteUrl,\n isPresent,\n isSameHost,\n now,\n parseSpaceSeparated,\n parseSpaceSeparatedSet,\n setsEqual,\n} from '@monocloud/auth-core/internal';\nimport {\n generateNonce,\n generatePKCE,\n generateState,\n isUserInGroup,\n mergeArrays,\n parseCallbackParams,\n} from '@monocloud/auth-core/utils';\nimport type {\n Authenticators,\n AuthorizationParams,\n DisplayOptions,\n IssuerMetadata,\n MonoCloudSession,\n Prompt,\n} from '@monocloud/auth-core';\nimport {\n MonoCloudOidcClient,\n MonoCloudOPError,\n MonoCloudTokenError,\n MonoCloudValidationError,\n} from '@monocloud/auth-core';\nimport { MonoCloudSessionService } from './monocloud-session-service';\nimport { MonoCloudStateService } from './monocloud-state-service';\nimport { getOptions } from './options/get-options';\nimport {\n ApplicationState,\n CallbackOptions,\n GetTokensOptions,\n MonoCloudOptions,\n MonoCloudOptionsBase,\n MonoCloudState,\n MonoCloudTokens,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from './types';\nimport {\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n MonoCloudRequest,\n MonoCloudResponse,\n} from './types/internal';\nimport {\n callbackOptionsSchema,\n getTokensOptionsSchema,\n resourceValidationSchema,\n scopesValidationSchema,\n signInOptionsSchema,\n signOutOptionsSchema,\n userInfoOptionsSchema,\n} from './options/validation';\nimport dbug, { Debugger } from 'debug';\n\n/**\n * @category Classes\n */\nexport class MonoCloudCoreClient {\n public readonly oidcClient: MonoCloudOidcClient;\n\n private readonly options: MonoCloudOptionsBase;\n\n private readonly stateService: MonoCloudStateService;\n\n private readonly sessionService: MonoCloudSessionService;\n\n private readonly debug: Debugger;\n\n private optionsValidated = false;\n\n constructor(partialOptions?: MonoCloudOptions) {\n this.options = getOptions(partialOptions, false);\n this.oidcClient = new MonoCloudOidcClient(\n this.options.tenantDomain,\n this.options.clientId,\n {\n clientSecret: this.options.clientSecret,\n idTokenSigningAlgorithm: this.options.idTokenSigningAlg,\n }\n );\n this.debug = dbug(this.options.debugger);\n this.stateService = new MonoCloudStateService(this.options);\n this.sessionService = new MonoCloudSessionService(this.options);\n\n /* v8 ignore next -- @preserve */\n if (process.env.DEBUG && !this.debug.enabled) {\n dbug.enable(process.env.DEBUG);\n }\n\n this.debug('Debug logging enabled.');\n }\n\n /**\n * Initiates the sign-in flow by redirecting the user to the MonoCloud authorization endpoint.\n *\n * This method handles scope and resource merging, state generation (nonce, state, PKCE),\n * and constructing the final authorization URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signInOptions - Configuration to customize the sign-in behavior.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} When validation of parameters or state fails.\n */\n async signIn(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signInOptions?: SignInOptions\n ): Promise<any> {\n this.debug('Starting sign-in handler');\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const indicatorResource = this.options.resources\n ?.map(x => x.resource)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n const indicatorScopes = this.options.resources\n ?.map(x => x.scopes)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n\n const mergedScopes = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.scopes),\n parseSpaceSeparated(this.options.defaultAuthParams.scopes),\n parseSpaceSeparated(indicatorScopes)\n ) ?? ['openid'];\n\n const mergedResources = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.resource),\n parseSpaceSeparated(this.options.defaultAuthParams.resource),\n parseSpaceSeparated(indicatorResource)\n );\n\n // Merge the sign-in options and the default options\n const opt = {\n ...(signInOptions ?? {}),\n authParams: {\n ...this.options.defaultAuthParams,\n ...signInOptions?.authParams,\n scopes: mergedScopes.join(' '),\n acrValues: mergeArrays(\n signInOptions?.authParams?.acrValues,\n this.options.defaultAuthParams.acrValues\n ),\n resource: mergedResources?.join(' '),\n },\n };\n\n let appState: ApplicationState = {};\n\n // Set the application state if the onSetApplicationState function is set\n if (this.options.onSetApplicationState) {\n appState = await this.options.onSetApplicationState(request);\n\n // Validate the custom sign-in state\n if (\n appState === null ||\n appState === undefined ||\n typeof appState !== 'object' ||\n Array.isArray(appState)\n ) {\n throw new MonoCloudValidationError(\n 'Invalid Application State. Expected state to be an object'\n );\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n returnUrl: request.getQuery('return_url') as string,\n authenticatorHint: request.getQuery(\n 'authenticator_hint'\n ) as Authenticators,\n scope: request.getQuery('scope') as string,\n resource: request.getQuery('resource') as string,\n display: request.getQuery('display') as DisplayOptions,\n uiLocales: request.getQuery('ui_locales') as string,\n acrValues: request.getQuery('acr_values') as string,\n loginHint: request.getQuery('login_hint') as string,\n prompt: request.getQuery('prompt') as Prompt,\n maxAge: parseInt(request.getQuery('max_age') as string, 10),\n }\n : {};\n\n // Set the return url if passed down\n const retUrl = query.returnUrl ?? opt.returnUrl;\n if (\n typeof retUrl === 'string' &&\n retUrl &&\n (!isAbsoluteUrl(retUrl) || isSameHost(this.options.appUrl, retUrl))\n ) {\n opt.returnUrl = retUrl;\n }\n\n // Validate the options\n const { error } = signInOptionsSchema.validate(opt, { abortEarly: true });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // Generate the state, nonce & code verifier\n const state = generateState();\n const nonce = generateNonce();\n const { codeChallenge, codeVerifier } = await generatePKCE();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (!isNaN(query.maxAge!)) {\n opt.authParams.maxAge = query.maxAge;\n }\n\n // Ensure that return to is present, if not then use the base url as the return to\n const returnUrl = encodeURIComponent(\n opt.returnUrl ?? this.options.appUrl\n );\n\n const redirectUrl = `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n // Create the Authorization Parameters\n let params: AuthorizationParams = {\n redirectUri: redirectUrl,\n ...opt.authParams,\n nonce,\n state,\n codeChallenge,\n };\n\n // Set the Authenticator if passed down\n const authenticatorHint =\n query.authenticatorHint ?? opt.authParams.authenticatorHint;\n if (typeof authenticatorHint === 'string' && authenticatorHint) {\n params.authenticatorHint = authenticatorHint;\n }\n\n const scopes =\n (typeof query.scope === 'string' ? query.scope : undefined) ??\n opt.authParams.scopes;\n\n if (scopes) {\n const { error: e } = scopesValidationSchema.validate(scopes, {\n abortEarly: true,\n });\n\n if (!e) {\n params.scopes = scopes;\n }\n }\n\n const resource =\n (typeof query.resource === 'string' ? query.resource : undefined) ??\n opt.authParams.resource;\n\n // Set the resources mode if passed down\n if (resource) {\n const { error: e } = resourceValidationSchema.validate(resource, {\n abortEarly: true,\n });\n\n if (!e) {\n params.resource = resource;\n }\n }\n\n // Set the display if passed down\n const display = query.display ?? opt.authParams.display;\n if (typeof display === 'string' && display) {\n params.display = display as unknown as DisplayOptions;\n }\n\n // Set the ui locales if passed down\n const uiLocales = query.uiLocales ?? opt.authParams.uiLocales;\n if (typeof uiLocales === 'string' && uiLocales) {\n params.uiLocales = uiLocales;\n }\n\n // Set the acr values if passed down\n const acrValues = query.acrValues ?? opt.authParams.acrValues;\n if (typeof acrValues === 'string' && acrValues) {\n params.acrValues = acrValues\n .split(' ')\n .map(x => x.trim())\n .filter(x => x !== '');\n }\n\n // Set the login hint if passed down\n const loginHint = query.loginHint ?? opt.authParams.loginHint;\n if (typeof loginHint === 'string' && loginHint) {\n params.loginHint = loginHint;\n }\n\n // Set the prompt if passed down\n let prompt: string | undefined;\n if (typeof query.prompt === 'string') {\n prompt = query.prompt;\n } else {\n prompt = opt.register ? 'create' : opt.authParams.prompt;\n }\n\n if (prompt) {\n params.prompt = prompt as Prompt;\n }\n\n /* v8 ignore next -- @preserve */\n if (!params.scopes || params.scopes.length < 0) {\n throw new MonoCloudValidationError(\n 'Scopes are required for signing in'\n );\n }\n\n // Generate the monocloud state\n const monoCloudState: MonoCloudState = {\n returnUrl,\n state,\n nonce,\n codeVerifier,\n maxAge: opt.authParams.maxAge,\n appState: JSON.stringify(appState),\n resource: this.options.defaultAuthParams.resource,\n scopes: params.scopes,\n };\n\n if (this.options.usePar) {\n const { request_uri } =\n await this.oidcClient.pushedAuthorizationRequest(params);\n\n params = {\n requestUri: request_uri,\n };\n }\n\n // Create authorize url\n const authUrl = await this.oidcClient.authorizationUrl(params);\n\n // Set the state cookie\n await this.stateService.setState(\n response,\n monoCloudState,\n params.responseMode === 'form_post' ? 'none' : undefined\n );\n // Redirect to authorize url\n response.redirect(authUrl, 302);\n } catch (error) {\n if (typeof signInOptions?.onError === 'function') {\n return signInOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles the OpenID callback after the user authenticates with MonoCloud.\n *\n * Processes the authorization code, validates the state and nonce, exchanges the code for tokens,\n * initializes the user session, and performs the final redirect to the application's return URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param callbackOptions - Optional configuration for the callback handler.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} If the state is mismatched or tokens are invalid.\n */\n async callback(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n callbackOptions?: CallbackOptions\n ): Promise<any> {\n this.debug('Starting callback handler');\n\n try {\n this.validateOptions();\n\n const { method, url, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get' && method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the callback Options\n if (callbackOptions) {\n const { error } = callbackOptionsSchema.validate(callbackOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the state value\n const monoCloudState = await this.stateService.getState(\n request,\n response\n );\n\n // Handle invalid state\n if (!monoCloudState) {\n throw new MonoCloudValidationError('Invalid Authentication State');\n }\n\n let fullUrl = url;\n\n // check if the url is a relative url\n if (!isAbsoluteUrl(url)) {\n fullUrl = `${this.options.appUrl}${ensureLeadingSlash(url)}`;\n }\n\n // Get the search parameters or the body\n const payload =\n method.toLowerCase() === 'post'\n ? new URLSearchParams(body)\n : new URL(fullUrl).searchParams;\n\n // Get the parameters returned from the server\n const callbackParams = parseCallbackParams(payload);\n\n if (callbackParams.state !== monoCloudState.state) {\n throw new MonoCloudValidationError('Invalid state');\n }\n\n if (isPresent(callbackParams.error)) {\n throw new MonoCloudOPError(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n callbackParams.error!,\n callbackParams.errorDescription\n );\n }\n\n // Get the redirect Url to be validated\n const redirectUri =\n callbackOptions?.redirectUri ??\n `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n if (!callbackParams.code) {\n throw new MonoCloudValidationError(\n 'Authorization code not found in callback params'\n );\n }\n\n // Parse the client state\n const appState: ApplicationState = JSON.parse(monoCloudState.appState);\n\n const session = await this.oidcClient.authenticate(\n callbackParams.code,\n redirectUri,\n monoCloudState.scopes,\n monoCloudState.resource,\n {\n codeVerifier: monoCloudState.codeVerifier,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenNonce: monoCloudState.nonce,\n idTokenMaxAge: monoCloudState.maxAge,\n idTokenClockTolerance: 5,\n fetchUserInfo:\n callbackOptions?.fetchUserInfo ?? this.options.fetchUserInfo,\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: async (s, i, u) =>\n await this.options.onSessionCreating?.(s, i, u, appState),\n }\n );\n\n // Set the user session\n await this.sessionService.setSession(request, response, session);\n\n // Return to base url if no return url was set\n if (!monoCloudState.returnUrl) {\n response.redirect(this.options.appUrl);\n return response.done();\n }\n\n // Return to a valid return to url\n try {\n const decodedUrl = decodeURIComponent(monoCloudState.returnUrl);\n\n if (!isAbsoluteUrl(decodedUrl)) {\n response.redirect(\n `${this.options.appUrl}${ensureLeadingSlash(decodedUrl)}`\n );\n return response.done();\n }\n\n if (isSameHost(this.options.appUrl, decodedUrl)) {\n response.redirect(decodedUrl);\n return response.done();\n }\n } catch {\n // do nothing\n }\n\n response.redirect(this.options.appUrl);\n } catch (error) {\n if (typeof callbackOptions?.onError === 'function') {\n return callbackOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Retrieves user information, optionally refetching fresh data from the UserInfo endpoint.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param userinfoOptions - Configuration to control refetching and error handling.\n * @returns A promise that resolves with the user information sent as a JSON response.\n *\n * @remarks\n * If `refresh` is true, the session is updated with fresh claims from the identity provider.\n */\n async userInfo(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n userinfoOptions?: UserInfoOptions\n ): Promise<any> {\n this.debug('Starting userinfo handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the User Info options\n if (userinfoOptions) {\n const { error } = userInfoOptionsSchema.validate(userinfoOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? { refresh: getBoolean(request.getQuery('refresh') as string) }\n : {};\n\n const refetchUserInfo =\n query.refresh ??\n userinfoOptions?.refresh ??\n this.options.refetchUserInfo;\n\n // Get the user session\n const session = await this.sessionService.getSession(\n request,\n response,\n !refetchUserInfo\n );\n\n // Handle no session\n if (!session) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n const defaultToken = findToken(\n session.accessTokens,\n this.options.defaultAuthParams.resource,\n session.authorizedScopes\n );\n\n // If refetch is false then return the session\n if (!refetchUserInfo || !defaultToken) {\n response.sendJson(session.user);\n return response.done();\n }\n\n // Get the new session\n const newSession = await this.oidcClient.refetchUserInfo(\n defaultToken,\n session,\n {\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n }\n );\n\n // Update the session containing the new claims\n const updated = await this.sessionService.updateSession(\n request,\n response,\n newSession\n );\n\n // Handle session was not updated successfully\n if (!updated) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n // Return the Claims\n response.sendJson(session.user);\n } catch (error) {\n if (typeof userinfoOptions?.onError === 'function') {\n return userinfoOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Initiates the sign-out flow, destroying the local session and optionally performing federated sign-out.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signOutOptions - Configuration for post-logout behavior and federated sign-out.\n *\n * @returns A promise that resolves when the sign-out redirection is initiated.\n */\n async signOut(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signOutOptions?: SignOutOptions\n ): Promise<any> {\n this.debug('Starting sign-out handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the sign-out options\n if (signOutOptions) {\n const { error } = signOutOptionsSchema.validate(signOutOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n postLogoutUrl: request.getQuery('post_logout_url') as string,\n federated: getBoolean(request.getQuery('federated') as string),\n }\n : {};\n\n // Build the return to url\n let returnUrl =\n this.options.postLogoutRedirectUri ??\n signOutOptions?.postLogoutRedirectUri ??\n this.options.appUrl;\n\n // Set the return url if passed down\n if (query.postLogoutUrl) {\n const { error } = signOutOptionsSchema.validate({\n postLogoutRedirectUri: query.postLogoutUrl,\n });\n\n if (!error) {\n returnUrl = query.postLogoutUrl;\n }\n }\n\n // Ensure the return to is an absolute one\n if (!isAbsoluteUrl(returnUrl)) {\n returnUrl = `${this.options.appUrl}${ensureLeadingSlash(returnUrl)}`;\n }\n\n // Get the current session\n const session = await this.sessionService.getSession(\n request,\n response,\n false\n );\n\n // Redirect to return url if session doesn't exist\n if (!session) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n await this.sessionService.removeSession(request, response);\n\n // Handle Federated Sign Out\n const isFederatedSignOut =\n query.federated ??\n signOutOptions?.federatedSignOut ??\n this.options.federatedSignOut;\n\n if (!isFederatedSignOut) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n // Build the end session Url\n const url = await this.oidcClient.endSessionUrl({\n idToken: session.idToken,\n postLogoutRedirectUri: returnUrl,\n state: signOutOptions?.state,\n });\n\n // Redirect the user to the end session endpoint\n response.redirect(url);\n } catch (error) {\n if (typeof signOutOptions?.onError === 'function') {\n return signOutOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles Back-Channel Logout notifications from the identity provider.\n *\n * Validates the Logout Token and triggers the `onBackChannelLogout` callback defined in options.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n *\n * @returns A promise that resolves when the logout notification has been processed.\n *\n * @throws {@link MonoCloudValidationError} If the logout token is missing or invalid.\n */\n async backChannelLogout(\n request: MonoCloudRequest,\n response: MonoCloudResponse\n ): Promise<any> {\n this.debug('Starting back-channel logout handler');\n\n try {\n this.validateOptions();\n\n response.setNoCache();\n\n if (!this.options.onBackChannelLogout) {\n response.notFound();\n return response.done();\n }\n\n const { method, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const params = new URLSearchParams(body);\n const logoutToken = params.get('logout_token');\n\n if (!logoutToken) {\n throw new MonoCloudValidationError('Missing Logout Token');\n }\n\n const metadata = await this.oidcClient.getMetadata();\n\n const { sid, sub } = await this.verifyLogoutToken(logoutToken, metadata);\n\n await this.options.onBackChannelLogout(sub, sid as any);\n\n response.noContent();\n } catch (error) {\n this.handleCatchAll(error as Error, response);\n }\n\n return response.done();\n }\n\n /**\n * Checks if the current request has an active and authenticated session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @returns `true` if a valid session with user data exists, `false` otherwise.\n *\n */\n async isAuthenticated(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<boolean> {\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n // Return true if the session exists\n return !!session?.user;\n }\n\n /**\n * Checks if the current session user belongs to the specified groups.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param groups - List of group names or IDs to check.\n * @param groupsClaim - Optional claim name that holds groups. Defaults to \"groups\".\n * @param matchAll - If `true`, requires membership in all groups; otherwise any one group is sufficient.\n *\n * @returns `true` if the user satisfies the group condition, `false` otherwise.\n */\n async isUserInGroup(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n groups: string[],\n groupsClaim?: string,\n matchAll?: boolean\n ): Promise<boolean> {\n const session = await this.sessionService.getSession(request, response);\n\n if (!session?.user) {\n return false;\n }\n\n return isUserInGroup(session.user, groups, groupsClaim, matchAll);\n }\n\n /**\n * Retrieves the current user's session data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @returns Session or `undefined`.\n */\n getSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<MonoCloudSession | undefined> {\n return this.sessionService.getSession(request, response);\n }\n\n /**\n * Updates the current user's session with new data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param session - The updated session object to persist.\n */\n async updateSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<void> {\n await this.sessionService.updateSession(request, response, session);\n }\n\n /**\n * Returns a copy of the current client configuration options.\n *\n * @returns A copy of the initialized configuration.\n */\n getOptions(): MonoCloudOptionsBase {\n return { ...this.options };\n }\n\n /**\n * Destroys the local user session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @remarks\n * This does not perform federated sign-out. For identity provider sign-out, use `signOut` handler.\n */\n destroySession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<void> {\n return this.sessionService.removeSession(request, response);\n }\n\n /**\n * Retrieves active tokens (Access, ID, Refresh), performing a refresh if they are expired or missing.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param options - Configuration for token retrieval (force refresh, specific scopes/resources).\n *\n * @returns Fetched tokens.\n *\n * @throws {@link MonoCloudValidationError} If the session does not exist or tokens cannot be found/refreshed.\n */\n async getTokens(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n options?: GetTokensOptions\n ): Promise<MonoCloudTokens> {\n // Validate the get tokens options\n if (options) {\n const { error } = getTokensOptionsSchema.validate(options, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n if (!session) {\n throw new MonoCloudValidationError('Session does not exist');\n }\n\n let scopes = options?.scopes;\n\n const resource =\n options?.resource ?? this.options.defaultAuthParams.resource;\n\n if (isPresent(options?.resource)) {\n if (!isPresent(scopes)) {\n // Check if there is a resource with undefined scope\n const noScopeResource = this.options.resources?.find(\n x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n ) && !x.scopes\n );\n\n // Search for the same resource with scopes defined\n if (!noScopeResource) {\n scopes = this.options.resources?.find(x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n )\n )?.scopes;\n }\n }\n }\n\n const findTokenScopes =\n !isPresent(options?.resource) && !isPresent(scopes)\n ? session.authorizedScopes\n : scopes;\n\n let token = findToken(session.accessTokens, resource, findTokenScopes);\n\n const tokenExpired = !!token && token.accessTokenExpiration - 30 < now();\n\n let { idToken } = session;\n let { refreshToken } = session;\n\n if (options?.forceRefresh || !token || tokenExpired) {\n if (!refreshToken && token && tokenExpired) {\n throw new MonoCloudTokenError(\n 'No refresh token available to refresh the expired access token'\n );\n }\n\n const updatedSession = await this.oidcClient.refreshSession(session, {\n fetchUserInfo: options?.refetchUserInfo ?? this.options.refetchUserInfo,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenClockTolerance: 5,\n refreshGrantOptions: {\n resource,\n scopes,\n },\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n });\n\n await this.sessionService.updateSession(\n request,\n response,\n updatedSession\n );\n\n token = findToken(\n updatedSession?.accessTokens,\n resource,\n findTokenScopes\n );\n\n idToken = updatedSession.idToken;\n refreshToken = updatedSession.refreshToken;\n }\n\n // Just in case. At this point, the access token should be present\n /* v8 ignore next -- @preserve */\n if (!token) {\n throw new MonoCloudValidationError('Access token not found');\n }\n\n return {\n ...token,\n idToken,\n refreshToken,\n isExpired: token.accessTokenExpiration - 30 < now(),\n };\n }\n\n private async verifyLogoutToken(\n token: string,\n metadata: IssuerMetadata\n ): Promise<JWTPayload> {\n const jwks = createRemoteJWKSet(new URL(metadata.jwks_uri));\n\n const { payload } = await jwtVerify(token, jwks, {\n issuer: metadata.issuer,\n audience: this.options.clientId,\n algorithms: [this.options.idTokenSigningAlg],\n requiredClaims: ['iat'],\n });\n\n if (\n (!payload.sid && !payload.sub) ||\n payload.nonce ||\n !payload.events ||\n typeof payload.events !== 'object'\n ) {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n const event = (payload.events as any)[\n 'http://schemas.openid.net/event/backchannel-logout'\n ];\n\n if (!event || typeof event !== 'object') {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n return payload;\n }\n\n private handleCatchAll(error: Error, res: MonoCloudResponse): void {\n // eslint-disable-next-line no-console\n console.error(error);\n res.internalServerError();\n }\n\n private validateOptions(): void {\n if (!this.optionsValidated) {\n this.optionsValidated = true;\n getOptions(this.options);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["cookie","Joi","MonoCloudValidationError","MonoCloudOidcClient","MonoCloudValidationError","MonoCloudOPError","MonoCloudTokenError"],"sources":["../src/monocloud-session-service.ts","../src/monocloud-state-service.ts","../src/options/defaults.ts","../src/options/validation.ts","../src/options/get-options.ts","../src/monocloud-node-core-client.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid';\nimport { serialize } from 'cookie';\nimport { decrypt, encrypt } from '@monocloud/auth-core/utils';\nimport type { MonoCloudSession, MonoCloudUser } from '@monocloud/auth-core';\nimport { now } from '@monocloud/auth-core/internal';\nimport { MonoCloudOptionsBase } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n SessionCookieValue,\n} from './types/internal';\n\nconst CHUNK_BYTE_SIZE = 4090;\n\nexport class MonoCloudSessionService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<string> {\n // Generate a session Id\n const key = uuid();\n\n // Set the issued and updated time\n const iat = now();\n const uat = iat;\n\n // Calculate the lifetime of the cookie\n const exp = this.getExpiry(iat, uat);\n\n // Set the Cookie Value\n const cookieValue: SessionCookieValue = {\n key,\n lifetime: { c: iat, u: uat, e: exp },\n };\n\n // Save the Session\n await this.saveSession(req, res, cookieValue, session);\n\n // Return the session Id\n return key;\n }\n\n async getSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n shouldResave = true\n ): Promise<MonoCloudSession | undefined> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return undefined;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // if there is no session store\n if (!this.options.session.store) {\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n\n // ensure that the cookie has a session\n if (!cookieValue.session) {\n return undefined;\n }\n\n // create a session object\n Object.assign(session, JSON.parse(JSON.stringify(cookieValue.session)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n // Get the session from the store\n const sessionObj = await this.options.session.store.get(cookieValue.key);\n\n // if there is no session in the store then delete the cookie\n if (!sessionObj) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Get the instance of the session\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n Object.assign(session, JSON.parse(JSON.stringify(sessionObj)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n async updateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<boolean> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return false;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return false;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // Save the session\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n\n return true;\n }\n\n async removeSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Delete the current session from the store\n /* v8 ignore else -- @preserve */\n if (cookieValue.key) {\n await this.options.session.store.delete(cookieValue.key);\n }\n }\n\n await this.deleteAllCookies(req, res);\n }\n\n private async validateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue\n ): Promise<boolean> {\n // Get the current time\n const nowTime = now();\n\n let isValid = true;\n\n // Ensure that the expiration has not passed\n if (cookieValue.lifetime.e && cookieValue.lifetime.e < nowTime) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not expired based on the last updated time\n if (\n this.options.session.sliding &&\n cookieValue.lifetime.u + this.options.session.duration < nowTime\n ) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not crossed the maximum duration allowed\n if (\n cookieValue.lifetime.c + this.options.session.maximumDuration <\n nowTime\n ) {\n isValid = false;\n }\n\n // return Is Valid if all ok\n if (isValid) {\n return true;\n }\n\n // If there is a session store then delete the session from the store\n if (this.options.session.store) {\n await this.options.session.store.delete(cookieValue.key);\n }\n\n await this.deleteAllCookies(req, res);\n\n return false;\n }\n\n private async saveSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue,\n session: MonoCloudSession\n ): Promise<void> {\n const cookies = new Set((await this.getRequestCookie(req))?.keys ?? []);\n\n // If no session store is present\n if (!this.options.session.store) {\n // Set the cookie session Value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = session;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Get the cookie containing the session Id\n const cookieData = await this.getCookieData(req);\n\n // Delete the current session from the store\n if (cookieData?.key) {\n await this.options.session.store.delete(cookieData.key);\n }\n\n // Ensure there is no session in the cookie value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = undefined;\n\n // Set the new session in the store\n await this.options.session.store.set(\n cookieValue.key,\n session,\n cookieValue.lifetime\n );\n }\n\n // Encrypt the cookie value\n const encryptedData = await encrypt(\n JSON.stringify(cookieValue),\n this.options.cookieSecret\n );\n\n const cookieExpiry = cookieValue.lifetime.e\n ? new Date(cookieValue.lifetime.e * 1000)\n : undefined;\n\n const cookieOptions = this.getCookieOptions(cookieExpiry);\n const chunkSize =\n CHUNK_BYTE_SIZE -\n serialize(`${this.options.session.cookie.name}.0`, '', cookieOptions)\n .length;\n\n // Calculate the number of cookie chunks\n const chunks = Math.ceil(encryptedData.length / chunkSize);\n\n for (let i = 0; i < chunks; i += 1) {\n const encryptedChunk = encryptedData.slice(\n i * chunkSize,\n (i + 1) * chunkSize\n );\n\n const cookieName =\n chunks === 1\n ? this.options.session.cookie.name\n : `${this.options.session.cookie.name}.${i}`;\n\n await res.setCookie(\n cookieName,\n encryptedChunk,\n this.getCookieOptions(cookieExpiry)\n );\n\n cookies.delete(cookieName);\n }\n\n // Delete all cookies which are not required anymore\n for (const cookie of cookies) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n\n private async getCookieData(\n req: IMonoCloudCookieRequest\n ): Promise<SessionCookieValue | undefined> {\n // Get all the cookies\n const cookieData = await this.getRequestCookie(req);\n\n // Handle no cookies\n if (!cookieData?.value) {\n return undefined;\n }\n\n // Decrypt the cookie\n const data = await decrypt(cookieData.value, this.options.cookieSecret);\n\n // Handle no data\n if (!data) {\n return undefined;\n }\n\n // Return the parsed session cookie value\n return JSON.parse(data);\n }\n\n private async getRequestCookie(\n req: IMonoCloudCookieRequest\n ): Promise<{ keys: string[]; value: string } | undefined> {\n // Get all the cookies\n const cookies = await req.getAllCookies();\n\n // Handle no cookies\n if (!cookies.size) {\n return undefined;\n }\n\n // If a cookie exists without chunks then return it\n const val = cookies.get(this.options.session.cookie.name);\n\n if (val) {\n return { keys: [this.options.session.cookie.name], value: val };\n }\n\n // Filter out the cookies and only keep the relevant ones\n const cookieValues = Array.from(cookies.entries())\n .filter(([cookie]) =>\n cookie.startsWith(`${this.options.session.cookie.name}.`)\n )\n .map(([cookie, value]) => ({\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n key: parseInt(cookie.split('.').pop() || '0', 10),\n value,\n }))\n .sort((a, b) => a.key - b.key);\n\n // Sort the cookies by chunk numbers\n const cookieValue = cookieValues.map(({ value }) => value).join('');\n\n // Handle empty cookie value\n if (!cookieValue) {\n return undefined;\n }\n\n // Return the cookie names and values\n return {\n keys: cookieValues.map(\n ({ key }) => `${this.options.session.cookie.name}.${key}`\n ),\n value: cookieValue,\n };\n }\n\n private getExpiry(iat: number, uat: number): number | undefined {\n // Return null if session is not persistent\n if (!this.options.session.cookie.persistent) {\n return undefined;\n }\n\n // If session is not sliding the return the absolute expiration\n if (!this.options.session.sliding) {\n return Math.floor(iat + this.options.session.duration);\n }\n\n // If session is sliding then return the lesser of the next extended time or the maximum duration\n return Math.floor(\n Math.min(\n uat + this.options.session.duration,\n iat + this.options.session.maximumDuration\n )\n );\n }\n\n private getCookieOptions(exp?: Date): CookieOptions {\n return {\n domain: this.options.session.cookie.domain,\n httpOnly: this.options.session.cookie.httpOnly,\n sameSite: this.options.session.cookie.sameSite,\n secure: this.options.session.cookie.secure,\n path: this.options.session.cookie.path,\n expires: exp,\n };\n }\n\n private async deleteAllCookies(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n const reqCookie = await this.getRequestCookie(req);\n\n const cookies = reqCookie?.keys?.filter(x =>\n x.startsWith(this.options.session.cookie.name)\n );\n\n for (const cookie of cookies ?? []) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n}\n","import { decryptAuthState, encryptAuthState } from '@monocloud/auth-core/utils';\nimport { MonoCloudOptionsBase, MonoCloudState, SameSiteValues } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n} from './types/internal';\n\nexport class MonoCloudStateService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setState(\n res: IMonoCloudCookieResponse,\n state: MonoCloudState,\n overrideSameSite?: SameSiteValues\n ): Promise<void> {\n await res.setCookie(\n this.options.state.cookie.name,\n await encryptAuthState(state, this.options.cookieSecret),\n this.getCookieOptions(overrideSameSite)\n );\n }\n\n async getState(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<MonoCloudState | undefined> {\n // Get the cookie\n const cookie = await req.getCookie(this.options.state.cookie.name);\n\n // Handle no cookie\n if (!cookie) {\n return undefined;\n }\n\n let decryptedResult: MonoCloudState;\n\n try {\n // Decrypt the cookie value\n decryptedResult = await decryptAuthState(\n cookie,\n this.options.cookieSecret\n );\n } catch {\n return undefined;\n }\n\n // Remove the cookie\n await res.setCookie(this.options.state.cookie.name, '', {\n ...this.getCookieOptions(),\n expires: new Date(0),\n });\n\n // return the state\n return decryptedResult;\n }\n\n private getCookieOptions(sameSite?: SameSiteValues): CookieOptions {\n return {\n domain: this.options.state.cookie.domain,\n httpOnly: this.options.state.cookie.httpOnly,\n sameSite: sameSite ?? this.options.state.cookie.sameSite,\n secure: this.options.state.cookie.secure,\n path: this.options.state.cookie.path,\n };\n }\n}\n","export const DEFAULT_OPTIONS = {\n routes: {\n callback: '/api/auth/callback',\n backChannelLogout: '/api/auth/backchannel-logout',\n signIn: '/api/auth/signin',\n signOut: '/api/auth/signout',\n userInfo: '/api/auth/userinfo',\n },\n clockSkew: 60,\n responseTimeout: 10000,\n usePar: false,\n fetchUserInfo: true,\n refetchUserInfo: false,\n federatedSignOut: true,\n defaultAuthParams: {\n scopes: 'openid profile email',\n responseType: 'code',\n },\n allowQueryParamOverrides: true,\n strictProfileSync: false,\n session: {\n cookie: {\n httpOnly: true,\n name: 'session',\n path: '/',\n sameSite: 'lax',\n persistent: true,\n },\n sliding: false,\n duration: 24 * 60 * 60,\n maximumDuration: 7 * 24 * 60 * 60,\n },\n state: {\n cookie: {\n httpOnly: true,\n name: 'state',\n path: '/',\n sameSite: 'lax',\n persistent: false,\n },\n },\n idTokenSigningAlg: 'RS256',\n filteredIdTokenClaims: [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n ],\n debugger: 'node-auth-core',\n userAgent: 'node-auth-core',\n};\n","import Joi from 'joi';\nimport type { AuthorizationParams } from '@monocloud/auth-core';\nimport {\n CallbackOptions,\n GetSessionOptions,\n GetTokensOptions,\n Indicator,\n MonoCloudOptionsBase,\n MonoCloudRoutes,\n MonoCloudSessionOptionsBase,\n MonoCloudStateOptions,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from '../types';\n\nconst stringRequired = Joi.string().required();\nconst stringOptional = Joi.string().optional();\nconst boolRequired = Joi.boolean().required();\nconst boolOptional = Joi.boolean().optional();\nconst numRequired = Joi.number().required();\nconst numOptional = Joi.number().optional();\nconst objectOptional = Joi.object().optional();\nconst funcOptional = Joi.function().optional();\n\nconst sessionCookieSchema = Joi.object({\n name: stringRequired,\n path: stringRequired.uri({ relativeOnly: true }),\n domain: stringOptional,\n httpOnly: boolRequired,\n secure: boolRequired.when(Joi.ref('/appUrl'), {\n is: Joi.string().pattern(/^https:/i),\n then: Joi.valid(true).messages({\n 'any.only':\n 'Cookie must be set to secure when app url protocol is https.',\n }),\n otherwise: Joi.valid(false),\n }),\n sameSite: stringRequired.valid('strict', 'lax', 'none'),\n persistent: boolRequired,\n}).required();\n\nconst resourceSchema = stringRequired.custom((value, helpers) => {\n let valid: boolean;\n try {\n const url = new URL(value);\n valid = url.searchParams.size === 0 && url.hash.length === 0;\n } catch {\n valid = false;\n }\n\n if (!valid) {\n return helpers.message({\n custom: 'Resource must be a valid URL without query or hash parameters',\n });\n }\n\n return value;\n});\n\nexport const resourceValidationSchema = Joi.string()\n .custom((value, helpers) => {\n const parts = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (parts.length === 0) {\n return helpers.message({ custom: 'Resource must not be empty' });\n }\n\n for (const part of parts) {\n const { error } = resourceSchema.validate(part);\n if (error) {\n return helpers.message({\n custom: `Invalid resource \"${part}\": ${error.message}`,\n });\n }\n }\n\n return parts.join(' ');\n })\n .messages({\n 'string.base': 'Resource must be a space-separated string of URLs',\n });\n\nconst sessionSchema: Joi.ObjectSchema<MonoCloudSessionOptionsBase> = Joi.object(\n {\n cookie: sessionCookieSchema,\n sliding: boolRequired,\n duration: numRequired.min(1),\n maximumDuration: numRequired.min(1).greater(Joi.ref('duration')),\n store: objectOptional,\n }\n).required();\n\nconst stateSchema: Joi.ObjectSchema<MonoCloudStateOptions> = Joi.object({\n cookie: sessionCookieSchema,\n}).required();\n\nconst scopesSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n if (!scopes.includes('openid')) {\n return helpers.message({ custom: 'Scope must contain openid' });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nconst authParamSchema: Joi.ObjectSchema<AuthorizationParams> = Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n resource: resourceValidationSchema.optional(),\n})\n .unknown(true)\n .required();\n\nconst optionalAuthParamSchema: Joi.ObjectSchema<AuthorizationParams> =\n Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n })\n .unknown(true)\n .optional();\n\nconst routesSchema: Joi.ObjectSchema<MonoCloudRoutes> = Joi.object({\n callback: stringRequired.uri({ relativeOnly: true }),\n backChannelLogout: stringRequired.uri({ relativeOnly: true }),\n signIn: stringRequired.uri({ relativeOnly: true }),\n signOut: stringRequired.uri({ relativeOnly: true }),\n userInfo: stringRequired.uri({ relativeOnly: true }),\n}).required();\n\nexport const scopesValidationSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nexport const indicatorOptionsSchema: Joi.ObjectSchema<Indicator> = Joi.object({\n resource: resourceValidationSchema,\n scopes: scopesValidationSchema.optional(),\n});\n\nexport const optionsSchema: Joi.ObjectSchema<MonoCloudOptionsBase> = Joi.object(\n {\n clientId: stringRequired,\n clientSecret: stringRequired,\n tenantDomain: stringRequired.uri(),\n cookieSecret: stringRequired.min(8),\n appUrl: stringRequired.uri(),\n routes: routesSchema,\n clockSkew: numRequired,\n responseTimeout: numRequired.min(1000),\n usePar: boolRequired,\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n federatedSignOut: boolRequired,\n fetchUserInfo: boolRequired,\n refetchUserInfo: boolRequired,\n allowQueryParamOverrides: boolRequired,\n strictProfileSync: boolRequired,\n defaultAuthParams: authParamSchema,\n resources: Joi.array<Indicator>().items(indicatorOptionsSchema).optional(),\n session: sessionSchema,\n state: stateSchema,\n idTokenSigningAlg: Joi.string().valid(\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512'\n ),\n filteredIdTokenClaims: Joi.array<string>().items(stringRequired),\n debugger: stringRequired,\n userAgent: stringRequired,\n jwksCacheDuration: numOptional,\n metadataCacheDuration: numOptional,\n onBackChannelLogout: funcOptional,\n onSetApplicationState: funcOptional,\n onSessionCreating: funcOptional,\n }\n);\n\nexport const signInOptionsSchema: Joi.ObjectSchema<SignInOptions> = Joi.object({\n returnUrl: stringOptional.uri({ allowRelative: true }),\n register: boolOptional,\n authParams: optionalAuthParamSchema,\n onError: funcOptional,\n});\n\nexport const callbackOptionsSchema: Joi.ObjectSchema<CallbackOptions> =\n Joi.object({\n fetchUserInfo: boolOptional,\n redirectUri: stringOptional.uri(),\n onError: funcOptional,\n });\n\nexport const userInfoOptionsSchema: Joi.ObjectSchema<UserInfoOptions> =\n Joi.object({\n refresh: boolOptional,\n onError: funcOptional,\n });\n\nexport const signOutOptionsSchema: Joi.ObjectSchema<SignOutOptions> =\n Joi.object({\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n idToken: stringOptional,\n state: stringOptional,\n federatedSignOut: boolOptional,\n onError: funcOptional,\n });\n\nexport const getTokensOptionsSchema: Joi.ObjectSchema<GetTokensOptions> =\n Joi.object({\n forceRefresh: boolOptional,\n refetchUserInfo: boolOptional,\n resource: resourceValidationSchema.optional(),\n scopes: scopesValidationSchema.optional(),\n });\n\nexport const getSessionOptionsSchema: Joi.ObjectSchema<GetSessionOptions> =\n Joi.object({\n refetchUserInfo: boolOptional,\n });\n","/* eslint-disable prefer-destructuring */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {\n getBoolean,\n getNumber,\n removeTrailingSlash,\n} from '@monocloud/auth-core/internal';\nimport {\n MonoCloudOptions,\n MonoCloudOptionsBase,\n SameSiteValues,\n} from '../types';\nimport { DEFAULT_OPTIONS } from './defaults';\nimport { optionsSchema } from './validation';\nimport {\n MonoCloudValidationError,\n SecurityAlgorithms,\n} from '@monocloud/auth-core';\n\nexport const getOptions = (\n options?: MonoCloudOptions,\n throwOnError = true\n): MonoCloudOptionsBase => {\n const MONOCLOUD_AUTH_CLIENT_ID = process.env.MONOCLOUD_AUTH_CLIENT_ID;\n const MONOCLOUD_AUTH_CLIENT_SECRET = process.env.MONOCLOUD_AUTH_CLIENT_SECRET;\n const MONOCLOUD_AUTH_TENANT_DOMAIN = process.env.MONOCLOUD_AUTH_TENANT_DOMAIN;\n const MONOCLOUD_AUTH_SCOPES = process.env.MONOCLOUD_AUTH_SCOPES;\n const MONOCLOUD_AUTH_COOKIE_SECRET = process.env.MONOCLOUD_AUTH_COOKIE_SECRET;\n const MONOCLOUD_AUTH_APP_URL = process.env.MONOCLOUD_AUTH_APP_URL;\n const MONOCLOUD_AUTH_CALLBACK_URL = process.env.MONOCLOUD_AUTH_CALLBACK_URL;\n const MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL =\n process.env.MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL;\n const MONOCLOUD_AUTH_SIGNIN_URL = process.env.MONOCLOUD_AUTH_SIGNIN_URL;\n const MONOCLOUD_AUTH_SIGNOUT_URL = process.env.MONOCLOUD_AUTH_SIGNOUT_URL;\n const MONOCLOUD_AUTH_USER_INFO_URL = process.env.MONOCLOUD_AUTH_USER_INFO_URL;\n const MONOCLOUD_AUTH_RESOURCE = process.env.MONOCLOUD_AUTH_RESOURCE;\n const MONOCLOUD_AUTH_CLOCK_SKEW = process.env.MONOCLOUD_AUTH_CLOCK_SKEW;\n const MONOCLOUD_AUTH_RESPONSE_TIMEOUT =\n process.env.MONOCLOUD_AUTH_RESPONSE_TIMEOUT;\n const MONOCLOUD_AUTH_USE_PAR = process.env.MONOCLOUD_AUTH_USE_PAR;\n const MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI =\n process.env.MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI;\n const MONOCLOUD_AUTH_FEDERATED_SIGNOUT =\n process.env.MONOCLOUD_AUTH_FEDERATED_SIGNOUT;\n const MONOCLOUD_AUTH_FETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;\n const MONOCLOUD_AUTH_REFETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;\n const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES =\n process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;\n const MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC =\n process.env.MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC;\n const MONOCLOUD_AUTH_SESSION_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;\n const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SECURE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_SESSION_SLIDING =\n process.env.MONOCLOUD_AUTH_SESSION_SLIDING;\n const MONOCLOUD_AUTH_SESSION_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_DURATION;\n const MONOCLOUD_AUTH_SESSION_MAX_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_MAX_DURATION;\n const MONOCLOUD_AUTH_STATE_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_NAME;\n const MONOCLOUD_AUTH_STATE_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PATH;\n const MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_STATE_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SECURE;\n const MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG =\n process.env.MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG;\n const MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS =\n process.env.MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS;\n const MONOCLOUD_AUTH_JWKS_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_JWKS_CACHE_DURATION;\n const MONOCLOUD_AUTH_METADATA_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_METADATA_CACHE_DURATION;\n\n const appUrl = options?.appUrl ?? MONOCLOUD_AUTH_APP_URL!;\n\n const opt: MonoCloudOptionsBase = {\n clientId: options?.clientId ?? MONOCLOUD_AUTH_CLIENT_ID!,\n clientSecret: options?.clientSecret ?? MONOCLOUD_AUTH_CLIENT_SECRET,\n tenantDomain: options?.tenantDomain ?? MONOCLOUD_AUTH_TENANT_DOMAIN!,\n defaultAuthParams: {\n ...(options?.defaultAuthParams ?? {}),\n scopes:\n options?.defaultAuthParams?.scopes ??\n MONOCLOUD_AUTH_SCOPES ??\n DEFAULT_OPTIONS.defaultAuthParams.scopes,\n responseType:\n options?.defaultAuthParams?.responseType ??\n (DEFAULT_OPTIONS.defaultAuthParams.responseType as any),\n resource: options?.defaultAuthParams?.resource ?? MONOCLOUD_AUTH_RESOURCE,\n },\n resources: options?.resources,\n cookieSecret: options?.cookieSecret ?? MONOCLOUD_AUTH_COOKIE_SECRET!,\n appUrl: removeTrailingSlash(appUrl),\n routes: {\n callback: removeTrailingSlash(\n options?.routes?.callback ??\n MONOCLOUD_AUTH_CALLBACK_URL ??\n DEFAULT_OPTIONS.routes.callback\n ),\n backChannelLogout: removeTrailingSlash(\n options?.routes?.backChannelLogout ??\n MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL ??\n DEFAULT_OPTIONS.routes.backChannelLogout\n ),\n signIn: removeTrailingSlash(\n options?.routes?.signIn ??\n MONOCLOUD_AUTH_SIGNIN_URL ??\n DEFAULT_OPTIONS.routes.signIn\n ),\n signOut: removeTrailingSlash(\n options?.routes?.signOut ??\n MONOCLOUD_AUTH_SIGNOUT_URL ??\n DEFAULT_OPTIONS.routes.signOut\n ),\n userInfo: removeTrailingSlash(\n options?.routes?.userInfo ??\n MONOCLOUD_AUTH_USER_INFO_URL ??\n DEFAULT_OPTIONS.routes.userInfo\n ),\n },\n clockSkew:\n options?.clockSkew ??\n getNumber(MONOCLOUD_AUTH_CLOCK_SKEW) ??\n DEFAULT_OPTIONS.clockSkew,\n responseTimeout:\n options?.responseTimeout ??\n getNumber(MONOCLOUD_AUTH_RESPONSE_TIMEOUT) ??\n DEFAULT_OPTIONS.responseTimeout,\n usePar:\n options?.usePar ??\n getBoolean(MONOCLOUD_AUTH_USE_PAR) ??\n DEFAULT_OPTIONS.usePar,\n postLogoutRedirectUri:\n options?.postLogoutRedirectUri ?? MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI,\n federatedSignOut:\n options?.federatedSignOut ??\n getBoolean(MONOCLOUD_AUTH_FEDERATED_SIGNOUT) ??\n DEFAULT_OPTIONS.federatedSignOut,\n fetchUserInfo:\n options?.fetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_FETCH_USER_INFO) ??\n DEFAULT_OPTIONS.fetchUserInfo,\n refetchUserInfo:\n options?.refetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_REFETCH_USER_INFO) ??\n DEFAULT_OPTIONS.refetchUserInfo,\n allowQueryParamOverrides:\n options?.allowQueryParamOverrides ??\n getBoolean(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ??\n DEFAULT_OPTIONS.allowQueryParamOverrides,\n strictProfileSync:\n options?.strictProfileSync ??\n getBoolean(MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC) ??\n DEFAULT_OPTIONS.strictProfileSync,\n session: {\n cookie: {\n name:\n options?.session?.cookie?.name ??\n MONOCLOUD_AUTH_SESSION_COOKIE_NAME ??\n DEFAULT_OPTIONS.session.cookie.name,\n path:\n options?.session?.cookie?.path ??\n MONOCLOUD_AUTH_SESSION_COOKIE_PATH ??\n DEFAULT_OPTIONS.session.cookie.path,\n domain:\n options?.session?.cookie?.domain ??\n MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN,\n httpOnly:\n options?.session?.cookie?.httpOnly ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY) ??\n DEFAULT_OPTIONS.session.cookie.httpOnly,\n secure:\n options?.session?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.session?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.session.cookie.sameSite,\n persistent:\n options?.session?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.session.cookie.persistent,\n },\n sliding:\n options?.session?.sliding ??\n getBoolean(MONOCLOUD_AUTH_SESSION_SLIDING) ??\n DEFAULT_OPTIONS.session.sliding,\n duration:\n options?.session?.duration ??\n getNumber(MONOCLOUD_AUTH_SESSION_DURATION) ??\n DEFAULT_OPTIONS.session.duration,\n maximumDuration:\n options?.session?.maximumDuration ??\n getNumber(MONOCLOUD_AUTH_SESSION_MAX_DURATION) ??\n DEFAULT_OPTIONS.session.maximumDuration,\n store: options?.session?.store,\n },\n state: {\n cookie: {\n name:\n options?.state?.cookie?.name ??\n MONOCLOUD_AUTH_STATE_COOKIE_NAME ??\n DEFAULT_OPTIONS.state.cookie.name,\n path:\n options?.state?.cookie?.path ??\n MONOCLOUD_AUTH_STATE_COOKIE_PATH ??\n DEFAULT_OPTIONS.state.cookie.path,\n domain:\n options?.state?.cookie?.domain ?? MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN,\n httpOnly: DEFAULT_OPTIONS.state.cookie.httpOnly,\n secure:\n options?.state?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.state?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.state.cookie.sameSite,\n persistent:\n options?.state?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.state.cookie.persistent,\n },\n },\n idTokenSigningAlg:\n options?.idTokenSigningAlg ??\n (MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG as SecurityAlgorithms) ??\n DEFAULT_OPTIONS.idTokenSigningAlg,\n filteredIdTokenClaims:\n options?.filteredIdTokenClaims ??\n MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS?.split(' ')\n .map(x => x.trim())\n .filter(x => x.length) ??\n DEFAULT_OPTIONS.filteredIdTokenClaims,\n debugger: options?.debugger ?? DEFAULT_OPTIONS.debugger,\n userAgent: options?.userAgent ?? DEFAULT_OPTIONS.userAgent,\n jwksCacheDuration:\n options?.jwksCacheDuration ??\n getNumber(MONOCLOUD_AUTH_JWKS_CACHE_DURATION),\n metadataCacheDuration:\n options?.metadataCacheDuration ??\n getNumber(MONOCLOUD_AUTH_METADATA_CACHE_DURATION),\n onBackChannelLogout: options?.onBackChannelLogout,\n onSetApplicationState: options?.onSetApplicationState,\n onSessionCreating: options?.onSessionCreating,\n };\n\n const { value, error } = optionsSchema.validate(opt, { abortEarly: false });\n\n const requiredEnv: Record<string, string> = {\n tenantDomain: 'MONOCLOUD_AUTH_TENANT_DOMAIN',\n clientId: 'MONOCLOUD_AUTH_CLIENT_ID',\n clientSecret: 'MONOCLOUD_AUTH_CLIENT_SECRET',\n appUrl: 'MONOCLOUD_AUTH_APP_URL',\n cookieSecret: 'MONOCLOUD_AUTH_COOKIE_SECRET',\n };\n\n if (error) {\n if (throwOnError) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n 'WARNING: One or more configuration options were not provided for MonoCloudClient.'\n );\n error.details.forEach(detail => {\n if (detail.context?.key && requiredEnv[detail.context.key]) {\n // eslint-disable-next-line no-console\n console.warn(\n `Missing: ${detail.context.key} - Set ${requiredEnv[detail.context.key]} environment variable in your .env file.`\n );\n }\n });\n }\n\n return value;\n};\n","import { createRemoteJWKSet, JWTPayload, jwtVerify } from 'jose';\nimport {\n ensureLeadingSlash,\n findToken,\n getBoolean,\n isAbsoluteUrl,\n isPresent,\n isSameHost,\n now,\n parseSpaceSeparated,\n parseSpaceSeparatedSet,\n setsEqual,\n} from '@monocloud/auth-core/internal';\nimport {\n generateNonce,\n generatePKCE,\n generateState,\n isUserInGroup,\n mergeArrays,\n parseCallbackParams,\n} from '@monocloud/auth-core/utils';\nimport type {\n Authenticators,\n AuthorizationParams,\n DisplayOptions,\n IssuerMetadata,\n MonoCloudSession,\n Prompt,\n} from '@monocloud/auth-core';\nimport {\n MonoCloudOidcClient,\n MonoCloudOPError,\n MonoCloudTokenError,\n MonoCloudValidationError,\n} from '@monocloud/auth-core';\nimport { MonoCloudSessionService } from './monocloud-session-service';\nimport { MonoCloudStateService } from './monocloud-state-service';\nimport { getOptions } from './options/get-options';\nimport {\n ApplicationState,\n CallbackOptions,\n GetSessionOptions,\n GetTokensOptions,\n MonoCloudOptions,\n MonoCloudOptionsBase,\n MonoCloudState,\n MonoCloudTokens,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from './types';\nimport {\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n MonoCloudRequest,\n MonoCloudResponse,\n} from './types/internal';\nimport {\n callbackOptionsSchema,\n getSessionOptionsSchema,\n getTokensOptionsSchema,\n resourceValidationSchema,\n scopesValidationSchema,\n signInOptionsSchema,\n signOutOptionsSchema,\n userInfoOptionsSchema,\n} from './options/validation';\nimport dbug, { Debugger } from 'debug';\n\n/**\n * @category Classes\n */\nexport class MonoCloudCoreClient {\n public readonly oidcClient: MonoCloudOidcClient;\n\n private readonly options: MonoCloudOptionsBase;\n\n private readonly stateService: MonoCloudStateService;\n\n private readonly sessionService: MonoCloudSessionService;\n\n private readonly debug: Debugger;\n\n private optionsValidated = false;\n\n constructor(partialOptions?: MonoCloudOptions) {\n this.options = getOptions(partialOptions, false);\n this.oidcClient = new MonoCloudOidcClient(\n this.options.tenantDomain,\n this.options.clientId,\n {\n clientSecret: this.options.clientSecret,\n idTokenSigningAlgorithm: this.options.idTokenSigningAlg,\n }\n );\n this.debug = dbug(this.options.debugger);\n this.stateService = new MonoCloudStateService(this.options);\n this.sessionService = new MonoCloudSessionService(this.options);\n\n /* v8 ignore next -- @preserve */\n if (process.env.DEBUG && !this.debug.enabled) {\n dbug.enable(process.env.DEBUG);\n }\n\n this.debug('Debug logging enabled.');\n }\n\n /**\n * Initiates the sign-in flow by redirecting the user to the MonoCloud authorization endpoint.\n *\n * This method handles scope and resource merging, state generation (nonce, state, PKCE),\n * and constructing the final authorization URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signInOptions - Configuration to customize the sign-in behavior.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} When validation of parameters or state fails.\n */\n async signIn(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signInOptions?: SignInOptions\n ): Promise<any> {\n this.debug('Starting sign-in handler');\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const indicatorResource = this.options.resources\n ?.map(x => x.resource)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n const indicatorScopes = this.options.resources\n ?.map(x => x.scopes)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n\n const mergedScopes = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.scopes),\n parseSpaceSeparated(this.options.defaultAuthParams.scopes),\n parseSpaceSeparated(indicatorScopes)\n ) ?? ['openid'];\n\n const mergedResources = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.resource),\n parseSpaceSeparated(this.options.defaultAuthParams.resource),\n parseSpaceSeparated(indicatorResource)\n );\n\n // Merge the sign-in options and the default options\n const opt = {\n ...(signInOptions ?? {}),\n authParams: {\n ...this.options.defaultAuthParams,\n ...signInOptions?.authParams,\n scopes: mergedScopes.join(' '),\n acrValues: mergeArrays(\n signInOptions?.authParams?.acrValues,\n this.options.defaultAuthParams.acrValues\n ),\n resource: mergedResources?.join(' '),\n },\n };\n\n let appState: ApplicationState = {};\n\n // Set the application state if the onSetApplicationState function is set\n if (this.options.onSetApplicationState) {\n appState = await this.options.onSetApplicationState(request);\n\n // Validate the custom sign-in state\n if (\n appState === null ||\n appState === undefined ||\n typeof appState !== 'object' ||\n Array.isArray(appState)\n ) {\n throw new MonoCloudValidationError(\n 'Invalid Application State. Expected state to be an object'\n );\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n returnUrl: request.getQuery('return_url') as string,\n authenticatorHint: request.getQuery(\n 'authenticator_hint'\n ) as Authenticators,\n scope: request.getQuery('scope') as string,\n resource: request.getQuery('resource') as string,\n display: request.getQuery('display') as DisplayOptions,\n uiLocales: request.getQuery('ui_locales') as string,\n acrValues: request.getQuery('acr_values') as string,\n loginHint: request.getQuery('login_hint') as string,\n prompt: request.getQuery('prompt') as Prompt,\n maxAge: parseInt(request.getQuery('max_age') as string, 10),\n }\n : {};\n\n // Set the return url if passed down\n const retUrl = query.returnUrl ?? opt.returnUrl;\n if (\n typeof retUrl === 'string' &&\n retUrl &&\n (!isAbsoluteUrl(retUrl) || isSameHost(this.options.appUrl, retUrl))\n ) {\n opt.returnUrl = retUrl;\n }\n\n // Validate the options\n const { error } = signInOptionsSchema.validate(opt, { abortEarly: true });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // Generate the state, nonce & code verifier\n const state = generateState();\n const nonce = generateNonce();\n const { codeChallenge, codeVerifier } = await generatePKCE();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (!isNaN(query.maxAge!)) {\n opt.authParams.maxAge = query.maxAge;\n }\n\n // Ensure that return to is present, if not then use the base url as the return to\n const returnUrl = encodeURIComponent(\n opt.returnUrl ?? this.options.appUrl\n );\n\n const redirectUrl = `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n // Create the Authorization Parameters\n let params: AuthorizationParams = {\n redirectUri: redirectUrl,\n ...opt.authParams,\n nonce,\n state,\n codeChallenge,\n };\n\n // Set the Authenticator if passed down\n const authenticatorHint =\n query.authenticatorHint ?? opt.authParams.authenticatorHint;\n if (typeof authenticatorHint === 'string' && authenticatorHint) {\n params.authenticatorHint = authenticatorHint;\n }\n\n const scopes =\n (typeof query.scope === 'string' ? query.scope : undefined) ??\n opt.authParams.scopes;\n\n if (scopes) {\n const { error: e } = scopesValidationSchema.validate(scopes, {\n abortEarly: true,\n });\n\n if (!e) {\n params.scopes = scopes;\n }\n }\n\n const resource =\n (typeof query.resource === 'string' ? query.resource : undefined) ??\n opt.authParams.resource;\n\n // Set the resources mode if passed down\n if (resource) {\n const { error: e } = resourceValidationSchema.validate(resource, {\n abortEarly: true,\n });\n\n if (!e) {\n params.resource = resource;\n }\n }\n\n // Set the display if passed down\n const display = query.display ?? opt.authParams.display;\n if (typeof display === 'string' && display) {\n params.display = display as unknown as DisplayOptions;\n }\n\n // Set the ui locales if passed down\n const uiLocales = query.uiLocales ?? opt.authParams.uiLocales;\n if (typeof uiLocales === 'string' && uiLocales) {\n params.uiLocales = uiLocales;\n }\n\n // Set the acr values if passed down\n const acrValues = query.acrValues ?? opt.authParams.acrValues;\n if (typeof acrValues === 'string' && acrValues) {\n params.acrValues = acrValues\n .split(' ')\n .map(x => x.trim())\n .filter(x => x !== '');\n }\n\n // Set the login hint if passed down\n const loginHint = query.loginHint ?? opt.authParams.loginHint;\n if (typeof loginHint === 'string' && loginHint) {\n params.loginHint = loginHint;\n }\n\n // Set the prompt if passed down\n let prompt: string | undefined;\n if (typeof query.prompt === 'string') {\n prompt = query.prompt;\n } else {\n prompt = opt.register ? 'create' : opt.authParams.prompt;\n }\n\n if (prompt) {\n params.prompt = prompt as Prompt;\n }\n\n /* v8 ignore next -- @preserve */\n if (!params.scopes || params.scopes.length < 0) {\n throw new MonoCloudValidationError(\n 'Scopes are required for signing in'\n );\n }\n\n // Generate the monocloud state\n const monoCloudState: MonoCloudState = {\n returnUrl,\n state,\n nonce,\n codeVerifier,\n maxAge: opt.authParams.maxAge,\n appState: JSON.stringify(appState),\n resource: this.options.defaultAuthParams.resource,\n scopes: params.scopes,\n };\n\n if (this.options.usePar) {\n const { request_uri } =\n await this.oidcClient.pushedAuthorizationRequest(params);\n\n params = {\n requestUri: request_uri,\n };\n }\n\n // Create authorize url\n const authUrl = await this.oidcClient.authorizationUrl(params);\n\n // Set the state cookie\n await this.stateService.setState(\n response,\n monoCloudState,\n params.responseMode === 'form_post' ? 'none' : undefined\n );\n // Redirect to authorize url\n response.redirect(authUrl, 302);\n } catch (error) {\n if (typeof signInOptions?.onError === 'function') {\n return signInOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles the OpenID callback after the user authenticates with MonoCloud.\n *\n * Processes the authorization code, validates the state and nonce, exchanges the code for tokens,\n * initializes the user session, and performs the final redirect to the application's return URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param callbackOptions - Optional configuration for the callback handler.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} If the state is mismatched or tokens are invalid.\n */\n async callback(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n callbackOptions?: CallbackOptions\n ): Promise<any> {\n this.debug('Starting callback handler');\n\n try {\n this.validateOptions();\n\n const { method, url, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get' && method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the callback Options\n if (callbackOptions) {\n const { error } = callbackOptionsSchema.validate(callbackOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the state value\n const monoCloudState = await this.stateService.getState(\n request,\n response\n );\n\n // Handle invalid state\n if (!monoCloudState) {\n throw new MonoCloudValidationError('Invalid Authentication State');\n }\n\n let fullUrl = url;\n\n // check if the url is a relative url\n if (!isAbsoluteUrl(url)) {\n fullUrl = `${this.options.appUrl}${ensureLeadingSlash(url)}`;\n }\n\n // Get the search parameters or the body\n const payload =\n method.toLowerCase() === 'post'\n ? new URLSearchParams(body)\n : new URL(fullUrl).searchParams;\n\n // Get the parameters returned from the server\n const callbackParams = parseCallbackParams(payload);\n\n if (callbackParams.state !== monoCloudState.state) {\n throw new MonoCloudValidationError('Invalid state');\n }\n\n if (isPresent(callbackParams.error)) {\n throw new MonoCloudOPError(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n callbackParams.error!,\n callbackParams.errorDescription\n );\n }\n\n // Get the redirect Url to be validated\n const redirectUri =\n callbackOptions?.redirectUri ??\n `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n if (!callbackParams.code) {\n throw new MonoCloudValidationError(\n 'Authorization code not found in callback params'\n );\n }\n\n // Parse the client state\n const appState: ApplicationState = JSON.parse(monoCloudState.appState);\n\n const session = await this.oidcClient.authenticate(\n callbackParams.code,\n redirectUri,\n monoCloudState.scopes,\n monoCloudState.resource,\n {\n codeVerifier: monoCloudState.codeVerifier,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenNonce: monoCloudState.nonce,\n idTokenMaxAge: monoCloudState.maxAge,\n idTokenClockTolerance: 5,\n fetchUserInfo:\n callbackOptions?.fetchUserInfo ?? this.options.fetchUserInfo,\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: async (s, i, u) =>\n await this.options.onSessionCreating?.(s, i, u, appState),\n }\n );\n\n // Set the user session\n await this.sessionService.setSession(request, response, session);\n\n // Return to base url if no return url was set\n if (!monoCloudState.returnUrl) {\n response.redirect(this.options.appUrl);\n return response.done();\n }\n\n // Return to a valid return to url\n try {\n const decodedUrl = decodeURIComponent(monoCloudState.returnUrl);\n\n if (!isAbsoluteUrl(decodedUrl)) {\n response.redirect(\n `${this.options.appUrl}${ensureLeadingSlash(decodedUrl)}`\n );\n return response.done();\n }\n\n if (isSameHost(this.options.appUrl, decodedUrl)) {\n response.redirect(decodedUrl);\n return response.done();\n }\n } catch {\n // do nothing\n }\n\n response.redirect(this.options.appUrl);\n } catch (error) {\n if (typeof callbackOptions?.onError === 'function') {\n return callbackOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Retrieves user information, optionally refetching fresh data from the UserInfo endpoint.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param userinfoOptions - Configuration to control refetching and error handling.\n * @returns A promise that resolves with the user information sent as a JSON response.\n *\n * @remarks\n * If `refresh` is true, the session is updated with fresh claims from the identity provider.\n */\n async userInfo(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n userinfoOptions?: UserInfoOptions\n ): Promise<any> {\n this.debug('Starting userinfo handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the User Info options\n if (userinfoOptions) {\n const { error } = userInfoOptionsSchema.validate(userinfoOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? { refresh: getBoolean(request.getQuery('refresh') as string) }\n : {};\n\n const refetchUserInfo =\n query.refresh ??\n userinfoOptions?.refresh ??\n this.options.refetchUserInfo;\n\n // Get the user session\n const session = await this.sessionService.getSession(\n request,\n response,\n !refetchUserInfo\n );\n\n // Handle no session\n if (!session) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n const defaultToken = findToken(\n session.accessTokens,\n this.options.defaultAuthParams.resource,\n session.authorizedScopes\n );\n\n // If refetch is false then return the session\n if (!refetchUserInfo || !defaultToken) {\n response.sendJson(session.user);\n return response.done();\n }\n\n // Get the new session\n const newSession = await this.oidcClient.refetchUserInfo(\n defaultToken,\n session,\n {\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n strictProfileSync: this.options.strictProfileSync,\n }\n );\n\n // Update the session containing the new claims\n const updated = await this.sessionService.updateSession(\n request,\n response,\n newSession\n );\n\n // Handle session was not updated successfully\n if (!updated) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n // Return the Claims\n response.sendJson(session.user);\n } catch (error) {\n if (typeof userinfoOptions?.onError === 'function') {\n return userinfoOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Initiates the sign-out flow, destroying the local session and optionally performing federated sign-out.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signOutOptions - Configuration for post-logout behavior and federated sign-out.\n *\n * @returns A promise that resolves when the sign-out redirection is initiated.\n */\n async signOut(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signOutOptions?: SignOutOptions\n ): Promise<any> {\n this.debug('Starting sign-out handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the sign-out options\n if (signOutOptions) {\n const { error } = signOutOptionsSchema.validate(signOutOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n postLogoutUrl: request.getQuery('post_logout_url') as string,\n federated: getBoolean(request.getQuery('federated') as string),\n }\n : {};\n\n // Build the return to url\n let returnUrl =\n this.options.postLogoutRedirectUri ??\n signOutOptions?.postLogoutRedirectUri ??\n this.options.appUrl;\n\n // Set the return url if passed down\n if (query.postLogoutUrl) {\n const { error } = signOutOptionsSchema.validate({\n postLogoutRedirectUri: query.postLogoutUrl,\n });\n\n if (!error) {\n returnUrl = query.postLogoutUrl;\n }\n }\n\n // Ensure the return to is an absolute one\n if (!isAbsoluteUrl(returnUrl)) {\n returnUrl = `${this.options.appUrl}${ensureLeadingSlash(returnUrl)}`;\n }\n\n // Get the current session\n const session = await this.sessionService.getSession(\n request,\n response,\n false\n );\n\n // Redirect to return url if session doesn't exist\n if (!session) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n await this.sessionService.removeSession(request, response);\n\n // Handle Federated Sign Out\n const isFederatedSignOut =\n query.federated ??\n signOutOptions?.federatedSignOut ??\n this.options.federatedSignOut;\n\n if (!isFederatedSignOut) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n // Build the end session Url\n const url = await this.oidcClient.endSessionUrl({\n idToken: session.idToken,\n postLogoutRedirectUri: returnUrl,\n state: signOutOptions?.state,\n });\n\n // Redirect the user to the end session endpoint\n response.redirect(url);\n } catch (error) {\n if (typeof signOutOptions?.onError === 'function') {\n return signOutOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles Back-Channel Logout notifications from the identity provider.\n *\n * Validates the Logout Token and triggers the `onBackChannelLogout` callback defined in options.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n *\n * @returns A promise that resolves when the logout notification has been processed.\n *\n * @throws {@link MonoCloudValidationError} If the logout token is missing or invalid.\n */\n async backChannelLogout(\n request: MonoCloudRequest,\n response: MonoCloudResponse\n ): Promise<any> {\n this.debug('Starting back-channel logout handler');\n\n try {\n this.validateOptions();\n\n response.setNoCache();\n\n if (!this.options.onBackChannelLogout) {\n response.notFound();\n return response.done();\n }\n\n const { method, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const params = new URLSearchParams(body);\n const logoutToken = params.get('logout_token');\n\n if (!logoutToken) {\n throw new MonoCloudValidationError('Missing Logout Token');\n }\n\n const metadata = await this.oidcClient.getMetadata();\n\n const { sid, sub } = await this.verifyLogoutToken(logoutToken, metadata);\n\n await this.options.onBackChannelLogout(sub, sid as any);\n\n response.noContent();\n } catch (error) {\n this.handleCatchAll(error as Error, response);\n }\n\n return response.done();\n }\n\n /**\n * Checks if the current request has an active and authenticated session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @returns `true` if a valid session with user data exists, `false` otherwise.\n *\n */\n async isAuthenticated(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<boolean> {\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n // Return true if the session exists\n return !!session?.user;\n }\n\n /**\n * Checks if the current session user belongs to the specified groups.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param groups - List of group names or IDs to check.\n * @param groupsClaim - Optional claim name that holds groups. Defaults to \"groups\".\n * @param matchAll - If `true`, requires membership in all groups; otherwise any one group is sufficient.\n *\n * @returns `true` if the user satisfies the group condition, `false` otherwise.\n */\n async isUserInGroup(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n groups: string[],\n groupsClaim?: string,\n matchAll?: boolean\n ): Promise<boolean> {\n const session = await this.sessionService.getSession(request, response);\n\n if (!session?.user) {\n return false;\n }\n\n return isUserInGroup(session.user, groups, groupsClaim, matchAll);\n }\n\n /**\n * Retrieves the current user's session data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param options - Optional configuration to control session retrieval behavior.\n *\n * @returns Session or `undefined`.\n */\n async getSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n options?: GetSessionOptions\n ): Promise<MonoCloudSession | undefined> {\n if (options) {\n const { error } = getSessionOptionsSchema.validate(options, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const session = await this.sessionService.getSession(request, response);\n\n if (!options?.refetchUserInfo || !session) {\n return session;\n }\n\n const defaultToken = findToken(\n session.accessTokens,\n this.options.defaultAuthParams.resource,\n session.authorizedScopes\n );\n\n if (!defaultToken) {\n throw new MonoCloudValidationError('Access token not found');\n }\n\n const newSession = await this.oidcClient.refetchUserInfo(\n defaultToken,\n session,\n {\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n strictProfileSync: this.options.strictProfileSync,\n }\n );\n\n await this.sessionService.updateSession(request, response, newSession);\n\n return newSession;\n }\n\n /**\n * Updates the current user's session with new data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param session - The updated session object to persist.\n */\n async updateSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<void> {\n await this.sessionService.updateSession(request, response, session);\n }\n\n /**\n * Returns a copy of the current client configuration options.\n *\n * @returns A copy of the initialized configuration.\n */\n getOptions(): MonoCloudOptionsBase {\n return { ...this.options };\n }\n\n /**\n * Destroys the local user session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @remarks\n * This does not perform federated sign-out. For identity provider sign-out, use `signOut` handler.\n */\n destroySession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<void> {\n return this.sessionService.removeSession(request, response);\n }\n\n /**\n * Retrieves active tokens (Access, ID, Refresh), performing a refresh if they are expired or missing.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param options - Configuration for token retrieval (force refresh, specific scopes/resources).\n *\n * @returns Fetched tokens.\n *\n * @throws {@link MonoCloudValidationError} If the session does not exist or tokens cannot be found/refreshed.\n */\n async getTokens(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n options?: GetTokensOptions\n ): Promise<MonoCloudTokens> {\n // Validate the get tokens options\n if (options) {\n const { error } = getTokensOptionsSchema.validate(options, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n if (!session) {\n throw new MonoCloudValidationError('Session does not exist');\n }\n\n let scopes = options?.scopes;\n\n const resource =\n options?.resource ?? this.options.defaultAuthParams.resource;\n\n if (isPresent(options?.resource)) {\n if (!isPresent(scopes)) {\n // Check if there is a resource with undefined scope\n const noScopeResource = this.options.resources?.find(\n x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n ) && !x.scopes\n );\n\n // Search for the same resource with scopes defined\n if (!noScopeResource) {\n scopes = this.options.resources?.find(x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n )\n )?.scopes;\n }\n }\n }\n\n const findTokenScopes =\n !isPresent(options?.resource) && !isPresent(scopes)\n ? session.authorizedScopes\n : scopes;\n\n let token = findToken(session.accessTokens, resource, findTokenScopes);\n\n const tokenExpired = !!token && token.accessTokenExpiration - 30 < now();\n\n let { idToken } = session;\n let { refreshToken } = session;\n\n if (options?.forceRefresh || !token || tokenExpired) {\n if (!refreshToken && token && tokenExpired) {\n throw new MonoCloudTokenError(\n 'No refresh token available to refresh the expired access token'\n );\n }\n\n const updatedSession = await this.oidcClient.refreshSession(session, {\n fetchUserInfo: options?.refetchUserInfo ?? this.options.refetchUserInfo,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenClockTolerance: 5,\n refreshGrantOptions: {\n resource,\n scopes,\n },\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n strictProfileSync: this.options.strictProfileSync,\n });\n\n await this.sessionService.updateSession(\n request,\n response,\n updatedSession\n );\n\n token = findToken(\n updatedSession?.accessTokens,\n resource,\n findTokenScopes\n );\n\n idToken = updatedSession.idToken;\n refreshToken = updatedSession.refreshToken;\n }\n\n // Just in case. At this point, the access token should be present\n /* v8 ignore next -- @preserve */\n if (!token) {\n throw new MonoCloudValidationError('Access token not found');\n }\n\n return {\n ...token,\n idToken,\n refreshToken,\n isExpired: token.accessTokenExpiration - 30 < now(),\n };\n }\n\n private async verifyLogoutToken(\n token: string,\n metadata: IssuerMetadata\n ): Promise<JWTPayload> {\n const jwks = createRemoteJWKSet(new URL(metadata.jwks_uri));\n\n const { payload } = await jwtVerify(token, jwks, {\n issuer: metadata.issuer,\n audience: this.options.clientId,\n algorithms: [this.options.idTokenSigningAlg],\n requiredClaims: ['iat'],\n });\n\n if (\n (!payload.sid && !payload.sub) ||\n payload.nonce ||\n !payload.events ||\n typeof payload.events !== 'object'\n ) {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n const event = (payload.events as any)[\n 'http://schemas.openid.net/event/backchannel-logout'\n ];\n\n if (!event || typeof event !== 'object') {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n return payload;\n }\n\n private handleCatchAll(error: Error, res: MonoCloudResponse): void {\n // eslint-disable-next-line no-console\n console.error(error);\n res.internalServerError();\n }\n\n private validateOptions(): void {\n if (!this.optionsValidated) {\n this.optionsValidated = true;\n getOptions(this.options);\n }\n }\n}\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -503,6 +503,15 @@ interface MonoCloudOptionsBase {
503
503
  * @defaultValue false
504
504
  */
505
505
  allowQueryParamOverrides?: boolean;
506
+ /**
507
+ * Determines how user profile is updated when the session is updated.
508
+ *
509
+ * When enabled, the session user profile is fully replaced with a newly constructed profile
510
+ * derived from the latest ID token and, if applicable, the UserInfo response.
511
+ *
512
+ * @defaultValue false
513
+ */
514
+ strictProfileSync?: boolean;
506
515
  /**
507
516
  * Invoked when a back-channel logout request is received.
508
517
  */
@@ -848,6 +857,17 @@ interface GetTokensOptions extends RefreshGrantOptions$1 {
848
857
  */
849
858
  refetchUserInfo?: boolean;
850
859
  }
860
+ /**
861
+ * Options used to control session retrieval behavior when calling `getSession()`.
862
+ *
863
+ * @category Types
864
+ */
865
+ interface GetSessionOptions {
866
+ /**
867
+ * When enabled, re-fetches user information from the `UserInfo` endpoint and updates the current session.
868
+ */
869
+ refetchUserInfo?: boolean;
870
+ }
851
871
  //#endregion
852
872
  //#region src/monocloud-node-core-client.d.ts
853
873
  /**
@@ -951,10 +971,11 @@ declare class MonoCloudCoreClient {
951
971
  *
952
972
  * @param request - MonoCloud cookie request object.
953
973
  * @param response - MonoCloud cookie response object.
974
+ * @param options - Optional configuration to control session retrieval behavior.
954
975
  *
955
976
  * @returns Session or `undefined`.
956
977
  */
957
- getSession(request: IMonoCloudCookieRequest, response: IMonoCloudCookieResponse): Promise<MonoCloudSession$1 | undefined>;
978
+ getSession(request: IMonoCloudCookieRequest, response: IMonoCloudCookieResponse, options?: GetSessionOptions): Promise<MonoCloudSession$1 | undefined>;
958
979
  /**
959
980
  * Updates the current user's session with new data.
960
981
  *
@@ -996,5 +1017,5 @@ declare class MonoCloudCoreClient {
996
1017
  private validateOptions;
997
1018
  }
998
1019
  //#endregion
999
- export { type AccessToken, type Address, type ApplicationState, type AuthState, type AuthenticateOptions, type Authenticators, type AuthorizationParams, type CallbackOptions, type CallbackParams, type ClientAuthMethod, type CodeChallengeMethod, type CookieOptions, type DisplayOptions, type EndSessionParameters, type GetTokensOptions, type Group, type IMonoCloudCookieRequest, type IMonoCloudCookieResponse, type IdTokenClaims, type Indicator, type IssuerMetadata, type Jwk, type Jwks, type JwsHeaderParameters, MonoCloudAuthBaseError, type MonoCloudClientOptions, type MonoCloudCookieOptions, MonoCloudCoreClient, MonoCloudHttpError, MonoCloudOPError, type MonoCloudOptions, type MonoCloudOptionsBase, type MonoCloudRequest, type MonoCloudResponse, type MonoCloudRoutes, type MonoCloudSession, type MonoCloudSessionOptions, type MonoCloudSessionOptionsBase, type MonoCloudSessionStore, type MonoCloudStateOptions, type MonoCloudStatePartialOptions, MonoCloudTokenError, type MonoCloudTokens, type MonoCloudUser, MonoCloudValidationError, type OnBackChannelLogout, type OnCoreSessionCreating, type OnError, type OnSessionCreating, type OnSetApplicationState, type ParResponse, type Prompt, type PushedAuthorizationParams, type RefetchUserInfoOptions, type RefreshGrantOptions, type RefreshSessionOptions, type ResponseModes, type ResponseTypes, type SameSiteValues, type SecurityAlgorithms, type SerializeOptions, type SessionLifetime, type SetCookie, type SignInOptions, type SignOutOptions, type Tokens, type UserInfoOptions, type UserinfoResponse };
1020
+ export { type AccessToken, type Address, type ApplicationState, type AuthState, type AuthenticateOptions, type Authenticators, type AuthorizationParams, type CallbackOptions, type CallbackParams, type ClientAuthMethod, type CodeChallengeMethod, type CookieOptions, type DisplayOptions, type EndSessionParameters, type GetSessionOptions, type GetTokensOptions, type Group, type IMonoCloudCookieRequest, type IMonoCloudCookieResponse, type IdTokenClaims, type Indicator, type IssuerMetadata, type Jwk, type Jwks, type JwsHeaderParameters, MonoCloudAuthBaseError, type MonoCloudClientOptions, type MonoCloudCookieOptions, MonoCloudCoreClient, MonoCloudHttpError, MonoCloudOPError, type MonoCloudOptions, type MonoCloudOptionsBase, type MonoCloudRequest, type MonoCloudResponse, type MonoCloudRoutes, type MonoCloudSession, type MonoCloudSessionOptions, type MonoCloudSessionOptionsBase, type MonoCloudSessionStore, type MonoCloudStateOptions, type MonoCloudStatePartialOptions, MonoCloudTokenError, type MonoCloudTokens, type MonoCloudUser, MonoCloudValidationError, type OnBackChannelLogout, type OnCoreSessionCreating, type OnError, type OnSessionCreating, type OnSetApplicationState, type ParResponse, type Prompt, type PushedAuthorizationParams, type RefetchUserInfoOptions, type RefreshGrantOptions, type RefreshSessionOptions, type ResponseModes, type ResponseTypes, type SameSiteValues, type SecurityAlgorithms, type SerializeOptions, type SessionLifetime, type SetCookie, type SignInOptions, type SignOutOptions, type Tokens, type UserInfoOptions, type UserinfoResponse };
1000
1021
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -238,6 +238,7 @@ const DEFAULT_OPTIONS = {
238
238
  responseType: "code"
239
239
  },
240
240
  allowQueryParamOverrides: true,
241
+ strictProfileSync: false,
241
242
  session: {
242
243
  cookie: {
243
244
  httpOnly: true,
@@ -373,6 +374,7 @@ const optionsSchema = Joi.object({
373
374
  fetchUserInfo: boolRequired,
374
375
  refetchUserInfo: boolRequired,
375
376
  allowQueryParamOverrides: boolRequired,
377
+ strictProfileSync: boolRequired,
376
378
  defaultAuthParams: authParamSchema,
377
379
  resources: Joi.array().items(indicatorOptionsSchema).optional(),
378
380
  session: sessionSchema,
@@ -415,6 +417,7 @@ const getTokensOptionsSchema = Joi.object({
415
417
  resource: resourceValidationSchema.optional(),
416
418
  scopes: scopesValidationSchema.optional()
417
419
  });
420
+ const getSessionOptionsSchema = Joi.object({ refetchUserInfo: boolOptional });
418
421
 
419
422
  //#endregion
420
423
  //#region src/options/get-options.ts
@@ -440,6 +443,7 @@ const getOptions = (options, throwOnError = true) => {
440
443
  const MONOCLOUD_AUTH_FETCH_USER_INFO = process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;
441
444
  const MONOCLOUD_AUTH_REFETCH_USER_INFO = process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;
442
445
  const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES = process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;
446
+ const MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC = process.env.MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC;
443
447
  const MONOCLOUD_AUTH_SESSION_COOKIE_NAME = process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;
444
448
  const MONOCLOUD_AUTH_SESSION_COOKIE_PATH = process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;
445
449
  const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN = process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;
@@ -489,6 +493,7 @@ const getOptions = (options, throwOnError = true) => {
489
493
  fetchUserInfo: (options === null || options === void 0 ? void 0 : options.fetchUserInfo) ?? getBoolean(MONOCLOUD_AUTH_FETCH_USER_INFO) ?? DEFAULT_OPTIONS.fetchUserInfo,
490
494
  refetchUserInfo: (options === null || options === void 0 ? void 0 : options.refetchUserInfo) ?? getBoolean(MONOCLOUD_AUTH_REFETCH_USER_INFO) ?? DEFAULT_OPTIONS.refetchUserInfo,
491
495
  allowQueryParamOverrides: (options === null || options === void 0 ? void 0 : options.allowQueryParamOverrides) ?? getBoolean(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ?? DEFAULT_OPTIONS.allowQueryParamOverrides,
496
+ strictProfileSync: (options === null || options === void 0 ? void 0 : options.strictProfileSync) ?? getBoolean(MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC) ?? DEFAULT_OPTIONS.strictProfileSync,
492
497
  session: {
493
498
  cookie: {
494
499
  name: (options === null || options === void 0 || (_options$session = options.session) === null || _options$session === void 0 || (_options$session = _options$session.cookie) === null || _options$session === void 0 ? void 0 : _options$session.name) ?? MONOCLOUD_AUTH_SESSION_COOKIE_NAME ?? DEFAULT_OPTIONS.session.cookie.name,
@@ -791,7 +796,10 @@ var MonoCloudCoreClient = class {
791
796
  response.sendJson(session.user);
792
797
  return response.done();
793
798
  }
794
- const newSession = await this.oidcClient.refetchUserInfo(defaultToken, session, { onSessionCreating: (_this$options$onSessi2 = this.options.onSessionCreating) === null || _this$options$onSessi2 === void 0 ? void 0 : _this$options$onSessi2.bind(this) });
799
+ const newSession = await this.oidcClient.refetchUserInfo(defaultToken, session, {
800
+ onSessionCreating: (_this$options$onSessi2 = this.options.onSessionCreating) === null || _this$options$onSessi2 === void 0 ? void 0 : _this$options$onSessi2.bind(this),
801
+ strictProfileSync: this.options.strictProfileSync
802
+ });
795
803
  if (!await this.sessionService.updateSession(request, response, newSession)) {
796
804
  response.setNoCache();
797
805
  response.noContent();
@@ -929,11 +937,26 @@ var MonoCloudCoreClient = class {
929
937
  *
930
938
  * @param request - MonoCloud cookie request object.
931
939
  * @param response - MonoCloud cookie response object.
940
+ * @param options - Optional configuration to control session retrieval behavior.
932
941
  *
933
942
  * @returns Session or `undefined`.
934
943
  */
935
- getSession(request, response) {
936
- return this.sessionService.getSession(request, response);
944
+ async getSession(request, response, options) {
945
+ var _this$options$onSessi3;
946
+ if (options) {
947
+ const { error } = getSessionOptionsSchema.validate(options, { abortEarly: true });
948
+ if (error) throw new MonoCloudValidationError$1(error.details[0].message);
949
+ }
950
+ const session = await this.sessionService.getSession(request, response);
951
+ if (!(options === null || options === void 0 ? void 0 : options.refetchUserInfo) || !session) return session;
952
+ const defaultToken = findToken(session.accessTokens, this.options.defaultAuthParams.resource, session.authorizedScopes);
953
+ if (!defaultToken) throw new MonoCloudValidationError$1("Access token not found");
954
+ const newSession = await this.oidcClient.refetchUserInfo(defaultToken, session, {
955
+ onSessionCreating: (_this$options$onSessi3 = this.options.onSessionCreating) === null || _this$options$onSessi3 === void 0 ? void 0 : _this$options$onSessi3.bind(this),
956
+ strictProfileSync: this.options.strictProfileSync
957
+ });
958
+ await this.sessionService.updateSession(request, response, newSession);
959
+ return newSession;
937
960
  }
938
961
  /**
939
962
  * Updates the current user's session with new data.
@@ -1000,7 +1023,7 @@ var MonoCloudCoreClient = class {
1000
1023
  let { idToken } = session;
1001
1024
  let { refreshToken } = session;
1002
1025
  if ((options === null || options === void 0 ? void 0 : options.forceRefresh) || !token || tokenExpired) {
1003
- var _this$options$onSessi3;
1026
+ var _this$options$onSessi4;
1004
1027
  if (!refreshToken && token && tokenExpired) throw new MonoCloudTokenError$1("No refresh token available to refresh the expired access token");
1005
1028
  const updatedSession = await this.oidcClient.refreshSession(session, {
1006
1029
  fetchUserInfo: (options === null || options === void 0 ? void 0 : options.refetchUserInfo) ?? this.options.refetchUserInfo,
@@ -1012,7 +1035,8 @@ var MonoCloudCoreClient = class {
1012
1035
  scopes
1013
1036
  },
1014
1037
  filteredIdTokenClaims: this.options.filteredIdTokenClaims,
1015
- onSessionCreating: (_this$options$onSessi3 = this.options.onSessionCreating) === null || _this$options$onSessi3 === void 0 ? void 0 : _this$options$onSessi3.bind(this)
1038
+ onSessionCreating: (_this$options$onSessi4 = this.options.onSessionCreating) === null || _this$options$onSessi4 === void 0 ? void 0 : _this$options$onSessi4.bind(this),
1039
+ strictProfileSync: this.options.strictProfileSync
1016
1040
  });
1017
1041
  await this.sessionService.updateSession(request, response, updatedSession);
1018
1042
  token = findToken(updatedSession === null || updatedSession === void 0 ? void 0 : updatedSession.accessTokens, resource, findTokenScopes);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["uuid","MonoCloudValidationError","MonoCloudValidationError","MonoCloudOPError","MonoCloudTokenError"],"sources":["../src/monocloud-session-service.ts","../src/monocloud-state-service.ts","../src/options/defaults.ts","../src/options/validation.ts","../src/options/get-options.ts","../src/monocloud-node-core-client.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid';\nimport { serialize } from 'cookie';\nimport { decrypt, encrypt } from '@monocloud/auth-core/utils';\nimport type { MonoCloudSession, MonoCloudUser } from '@monocloud/auth-core';\nimport { now } from '@monocloud/auth-core/internal';\nimport { MonoCloudOptionsBase } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n SessionCookieValue,\n} from './types/internal';\n\nconst CHUNK_BYTE_SIZE = 4090;\n\nexport class MonoCloudSessionService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<string> {\n // Generate a session Id\n const key = uuid();\n\n // Set the issued and updated time\n const iat = now();\n const uat = iat;\n\n // Calculate the lifetime of the cookie\n const exp = this.getExpiry(iat, uat);\n\n // Set the Cookie Value\n const cookieValue: SessionCookieValue = {\n key,\n lifetime: { c: iat, u: uat, e: exp },\n };\n\n // Save the Session\n await this.saveSession(req, res, cookieValue, session);\n\n // Return the session Id\n return key;\n }\n\n async getSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n shouldResave = true\n ): Promise<MonoCloudSession | undefined> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return undefined;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // if there is no session store\n if (!this.options.session.store) {\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n\n // ensure that the cookie has a session\n if (!cookieValue.session) {\n return undefined;\n }\n\n // create a session object\n Object.assign(session, JSON.parse(JSON.stringify(cookieValue.session)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n // Get the session from the store\n const sessionObj = await this.options.session.store.get(cookieValue.key);\n\n // if there is no session in the store then delete the cookie\n if (!sessionObj) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Get the instance of the session\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n Object.assign(session, JSON.parse(JSON.stringify(sessionObj)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n async updateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<boolean> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return false;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return false;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // Save the session\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n\n return true;\n }\n\n async removeSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Delete the current session from the store\n /* v8 ignore else -- @preserve */\n if (cookieValue.key) {\n await this.options.session.store.delete(cookieValue.key);\n }\n }\n\n await this.deleteAllCookies(req, res);\n }\n\n private async validateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue\n ): Promise<boolean> {\n // Get the current time\n const nowTime = now();\n\n let isValid = true;\n\n // Ensure that the expiration has not passed\n if (cookieValue.lifetime.e && cookieValue.lifetime.e < nowTime) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not expired based on the last updated time\n if (\n this.options.session.sliding &&\n cookieValue.lifetime.u + this.options.session.duration < nowTime\n ) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not crossed the maximum duration allowed\n if (\n cookieValue.lifetime.c + this.options.session.maximumDuration <\n nowTime\n ) {\n isValid = false;\n }\n\n // return Is Valid if all ok\n if (isValid) {\n return true;\n }\n\n // If there is a session store then delete the session from the store\n if (this.options.session.store) {\n await this.options.session.store.delete(cookieValue.key);\n }\n\n await this.deleteAllCookies(req, res);\n\n return false;\n }\n\n private async saveSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue,\n session: MonoCloudSession\n ): Promise<void> {\n const cookies = new Set((await this.getRequestCookie(req))?.keys ?? []);\n\n // If no session store is present\n if (!this.options.session.store) {\n // Set the cookie session Value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = session;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Get the cookie containing the session Id\n const cookieData = await this.getCookieData(req);\n\n // Delete the current session from the store\n if (cookieData?.key) {\n await this.options.session.store.delete(cookieData.key);\n }\n\n // Ensure there is no session in the cookie value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = undefined;\n\n // Set the new session in the store\n await this.options.session.store.set(\n cookieValue.key,\n session,\n cookieValue.lifetime\n );\n }\n\n // Encrypt the cookie value\n const encryptedData = await encrypt(\n JSON.stringify(cookieValue),\n this.options.cookieSecret\n );\n\n const cookieExpiry = cookieValue.lifetime.e\n ? new Date(cookieValue.lifetime.e * 1000)\n : undefined;\n\n const cookieOptions = this.getCookieOptions(cookieExpiry);\n const chunkSize =\n CHUNK_BYTE_SIZE -\n serialize(`${this.options.session.cookie.name}.0`, '', cookieOptions)\n .length;\n\n // Calculate the number of cookie chunks\n const chunks = Math.ceil(encryptedData.length / chunkSize);\n\n for (let i = 0; i < chunks; i += 1) {\n const encryptedChunk = encryptedData.slice(\n i * chunkSize,\n (i + 1) * chunkSize\n );\n\n const cookieName =\n chunks === 1\n ? this.options.session.cookie.name\n : `${this.options.session.cookie.name}.${i}`;\n\n await res.setCookie(\n cookieName,\n encryptedChunk,\n this.getCookieOptions(cookieExpiry)\n );\n\n cookies.delete(cookieName);\n }\n\n // Delete all cookies which are not required anymore\n for (const cookie of cookies) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n\n private async getCookieData(\n req: IMonoCloudCookieRequest\n ): Promise<SessionCookieValue | undefined> {\n // Get all the cookies\n const cookieData = await this.getRequestCookie(req);\n\n // Handle no cookies\n if (!cookieData?.value) {\n return undefined;\n }\n\n // Decrypt the cookie\n const data = await decrypt(cookieData.value, this.options.cookieSecret);\n\n // Handle no data\n if (!data) {\n return undefined;\n }\n\n // Return the parsed session cookie value\n return JSON.parse(data);\n }\n\n private async getRequestCookie(\n req: IMonoCloudCookieRequest\n ): Promise<{ keys: string[]; value: string } | undefined> {\n // Get all the cookies\n const cookies = await req.getAllCookies();\n\n // Handle no cookies\n if (!cookies.size) {\n return undefined;\n }\n\n // If a cookie exists without chunks then return it\n const val = cookies.get(this.options.session.cookie.name);\n\n if (val) {\n return { keys: [this.options.session.cookie.name], value: val };\n }\n\n // Filter out the cookies and only keep the relevant ones\n const cookieValues = Array.from(cookies.entries())\n .filter(([cookie]) =>\n cookie.startsWith(`${this.options.session.cookie.name}.`)\n )\n .map(([cookie, value]) => ({\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n key: parseInt(cookie.split('.').pop() || '0', 10),\n value,\n }))\n .sort((a, b) => a.key - b.key);\n\n // Sort the cookies by chunk numbers\n const cookieValue = cookieValues.map(({ value }) => value).join('');\n\n // Handle empty cookie value\n if (!cookieValue) {\n return undefined;\n }\n\n // Return the cookie names and values\n return {\n keys: cookieValues.map(\n ({ key }) => `${this.options.session.cookie.name}.${key}`\n ),\n value: cookieValue,\n };\n }\n\n private getExpiry(iat: number, uat: number): number | undefined {\n // Return null if session is not persistent\n if (!this.options.session.cookie.persistent) {\n return undefined;\n }\n\n // If session is not sliding the return the absolute expiration\n if (!this.options.session.sliding) {\n return Math.floor(iat + this.options.session.duration);\n }\n\n // If session is sliding then return the lesser of the next extended time or the maximum duration\n return Math.floor(\n Math.min(\n uat + this.options.session.duration,\n iat + this.options.session.maximumDuration\n )\n );\n }\n\n private getCookieOptions(exp?: Date): CookieOptions {\n return {\n domain: this.options.session.cookie.domain,\n httpOnly: this.options.session.cookie.httpOnly,\n sameSite: this.options.session.cookie.sameSite,\n secure: this.options.session.cookie.secure,\n path: this.options.session.cookie.path,\n expires: exp,\n };\n }\n\n private async deleteAllCookies(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n const reqCookie = await this.getRequestCookie(req);\n\n const cookies = reqCookie?.keys?.filter(x =>\n x.startsWith(this.options.session.cookie.name)\n );\n\n for (const cookie of cookies ?? []) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n}\n","import { decryptAuthState, encryptAuthState } from '@monocloud/auth-core/utils';\nimport { MonoCloudOptionsBase, MonoCloudState, SameSiteValues } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n} from './types/internal';\n\nexport class MonoCloudStateService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setState(\n res: IMonoCloudCookieResponse,\n state: MonoCloudState,\n overrideSameSite?: SameSiteValues\n ): Promise<void> {\n await res.setCookie(\n this.options.state.cookie.name,\n await encryptAuthState(state, this.options.cookieSecret),\n this.getCookieOptions(overrideSameSite)\n );\n }\n\n async getState(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<MonoCloudState | undefined> {\n // Get the cookie\n const cookie = await req.getCookie(this.options.state.cookie.name);\n\n // Handle no cookie\n if (!cookie) {\n return undefined;\n }\n\n let decryptedResult: MonoCloudState;\n\n try {\n // Decrypt the cookie value\n decryptedResult = await decryptAuthState(\n cookie,\n this.options.cookieSecret\n );\n } catch {\n return undefined;\n }\n\n // Remove the cookie\n await res.setCookie(this.options.state.cookie.name, '', {\n ...this.getCookieOptions(),\n expires: new Date(0),\n });\n\n // return the state\n return decryptedResult;\n }\n\n private getCookieOptions(sameSite?: SameSiteValues): CookieOptions {\n return {\n domain: this.options.state.cookie.domain,\n httpOnly: this.options.state.cookie.httpOnly,\n sameSite: sameSite ?? this.options.state.cookie.sameSite,\n secure: this.options.state.cookie.secure,\n path: this.options.state.cookie.path,\n };\n }\n}\n","export const DEFAULT_OPTIONS = {\n routes: {\n callback: '/api/auth/callback',\n backChannelLogout: '/api/auth/backchannel-logout',\n signIn: '/api/auth/signin',\n signOut: '/api/auth/signout',\n userInfo: '/api/auth/userinfo',\n },\n clockSkew: 60,\n responseTimeout: 10000,\n usePar: false,\n fetchUserInfo: true,\n refetchUserInfo: false,\n federatedSignOut: true,\n defaultAuthParams: {\n scopes: 'openid profile email',\n responseType: 'code',\n },\n allowQueryParamOverrides: true,\n session: {\n cookie: {\n httpOnly: true,\n name: 'session',\n path: '/',\n sameSite: 'lax',\n persistent: true,\n },\n sliding: false,\n duration: 24 * 60 * 60,\n maximumDuration: 7 * 24 * 60 * 60,\n },\n state: {\n cookie: {\n httpOnly: true,\n name: 'state',\n path: '/',\n sameSite: 'lax',\n persistent: false,\n },\n },\n idTokenSigningAlg: 'RS256',\n filteredIdTokenClaims: [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n ],\n debugger: 'node-auth-core',\n userAgent: 'node-auth-core',\n};\n","import Joi from 'joi';\nimport type { AuthorizationParams } from '@monocloud/auth-core';\nimport {\n CallbackOptions,\n GetTokensOptions,\n Indicator,\n MonoCloudOptionsBase,\n MonoCloudRoutes,\n MonoCloudSessionOptionsBase,\n MonoCloudStateOptions,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from '../types';\n\nconst stringRequired = Joi.string().required();\nconst stringOptional = Joi.string().optional();\nconst boolRequired = Joi.boolean().required();\nconst boolOptional = Joi.boolean().optional();\nconst numRequired = Joi.number().required();\nconst numOptional = Joi.number().optional();\nconst objectOptional = Joi.object().optional();\nconst funcOptional = Joi.function().optional();\n\nconst sessionCookieSchema = Joi.object({\n name: stringRequired,\n path: stringRequired.uri({ relativeOnly: true }),\n domain: stringOptional,\n httpOnly: boolRequired,\n secure: boolRequired.when(Joi.ref('/appUrl'), {\n is: Joi.string().pattern(/^https:/i),\n then: Joi.valid(true).messages({\n 'any.only':\n 'Cookie must be set to secure when app url protocol is https.',\n }),\n otherwise: Joi.valid(false),\n }),\n sameSite: stringRequired.valid('strict', 'lax', 'none'),\n persistent: boolRequired,\n}).required();\n\nconst resourceSchema = stringRequired.custom((value, helpers) => {\n let valid: boolean;\n try {\n const url = new URL(value);\n valid = url.searchParams.size === 0 && url.hash.length === 0;\n } catch {\n valid = false;\n }\n\n if (!valid) {\n return helpers.message({\n custom: 'Resource must be a valid URL without query or hash parameters',\n });\n }\n\n return value;\n});\n\nexport const resourceValidationSchema = Joi.string()\n .custom((value, helpers) => {\n const parts = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (parts.length === 0) {\n return helpers.message({ custom: 'Resource must not be empty' });\n }\n\n for (const part of parts) {\n const { error } = resourceSchema.validate(part);\n if (error) {\n return helpers.message({\n custom: `Invalid resource \"${part}\": ${error.message}`,\n });\n }\n }\n\n return parts.join(' ');\n })\n .messages({\n 'string.base': 'Resource must be a space-separated string of URLs',\n });\n\nconst sessionSchema: Joi.ObjectSchema<MonoCloudSessionOptionsBase> = Joi.object(\n {\n cookie: sessionCookieSchema,\n sliding: boolRequired,\n duration: numRequired.min(1),\n maximumDuration: numRequired.min(1).greater(Joi.ref('duration')),\n store: objectOptional,\n }\n).required();\n\nconst stateSchema: Joi.ObjectSchema<MonoCloudStateOptions> = Joi.object({\n cookie: sessionCookieSchema,\n}).required();\n\nconst scopesSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n if (!scopes.includes('openid')) {\n return helpers.message({ custom: 'Scope must contain openid' });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nconst authParamSchema: Joi.ObjectSchema<AuthorizationParams> = Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n resource: resourceValidationSchema.optional(),\n})\n .unknown(true)\n .required();\n\nconst optionalAuthParamSchema: Joi.ObjectSchema<AuthorizationParams> =\n Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n })\n .unknown(true)\n .optional();\n\nconst routesSchema: Joi.ObjectSchema<MonoCloudRoutes> = Joi.object({\n callback: stringRequired.uri({ relativeOnly: true }),\n backChannelLogout: stringRequired.uri({ relativeOnly: true }),\n signIn: stringRequired.uri({ relativeOnly: true }),\n signOut: stringRequired.uri({ relativeOnly: true }),\n userInfo: stringRequired.uri({ relativeOnly: true }),\n}).required();\n\nexport const scopesValidationSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nexport const indicatorOptionsSchema: Joi.ObjectSchema<Indicator> = Joi.object({\n resource: resourceValidationSchema,\n scopes: scopesValidationSchema.optional(),\n});\n\nexport const optionsSchema: Joi.ObjectSchema<MonoCloudOptionsBase> = Joi.object(\n {\n clientId: stringRequired,\n clientSecret: stringRequired,\n tenantDomain: stringRequired.uri(),\n cookieSecret: stringRequired.min(8),\n appUrl: stringRequired.uri(),\n routes: routesSchema,\n clockSkew: numRequired,\n responseTimeout: numRequired.min(1000),\n usePar: boolRequired,\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n federatedSignOut: boolRequired,\n fetchUserInfo: boolRequired,\n refetchUserInfo: boolRequired,\n allowQueryParamOverrides: boolRequired,\n defaultAuthParams: authParamSchema,\n resources: Joi.array<Indicator>().items(indicatorOptionsSchema).optional(),\n session: sessionSchema,\n state: stateSchema,\n idTokenSigningAlg: Joi.string().valid(\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512'\n ),\n filteredIdTokenClaims: Joi.array<string>().items(stringRequired),\n debugger: stringRequired,\n userAgent: stringRequired,\n jwksCacheDuration: numOptional,\n metadataCacheDuration: numOptional,\n onBackChannelLogout: funcOptional,\n onSetApplicationState: funcOptional,\n onSessionCreating: funcOptional,\n }\n);\n\nexport const signInOptionsSchema: Joi.ObjectSchema<SignInOptions> = Joi.object({\n returnUrl: stringOptional.uri({ allowRelative: true }),\n register: boolOptional,\n authParams: optionalAuthParamSchema,\n onError: funcOptional,\n});\n\nexport const callbackOptionsSchema: Joi.ObjectSchema<CallbackOptions> =\n Joi.object({\n fetchUserInfo: boolOptional,\n redirectUri: stringOptional.uri(),\n onError: funcOptional,\n });\n\nexport const userInfoOptionsSchema: Joi.ObjectSchema<UserInfoOptions> =\n Joi.object({\n refresh: boolOptional,\n onError: funcOptional,\n });\n\nexport const signOutOptionsSchema: Joi.ObjectSchema<SignOutOptions> =\n Joi.object({\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n idToken: stringOptional,\n state: stringOptional,\n federatedSignOut: boolOptional,\n onError: funcOptional,\n });\n\nexport const getTokensOptionsSchema: Joi.ObjectSchema<GetTokensOptions> =\n Joi.object({\n forceRefresh: boolOptional,\n refetchUserInfo: boolOptional,\n resource: resourceValidationSchema.optional(),\n scopes: scopesValidationSchema.optional(),\n });\n","/* eslint-disable prefer-destructuring */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {\n getBoolean,\n getNumber,\n removeTrailingSlash,\n} from '@monocloud/auth-core/internal';\nimport {\n MonoCloudOptions,\n MonoCloudOptionsBase,\n SameSiteValues,\n} from '../types';\nimport { DEFAULT_OPTIONS } from './defaults';\nimport { optionsSchema } from './validation';\nimport {\n MonoCloudValidationError,\n SecurityAlgorithms,\n} from '@monocloud/auth-core';\n\nexport const getOptions = (\n options?: MonoCloudOptions,\n throwOnError = true\n): MonoCloudOptionsBase => {\n const MONOCLOUD_AUTH_CLIENT_ID = process.env.MONOCLOUD_AUTH_CLIENT_ID;\n const MONOCLOUD_AUTH_CLIENT_SECRET = process.env.MONOCLOUD_AUTH_CLIENT_SECRET;\n const MONOCLOUD_AUTH_TENANT_DOMAIN = process.env.MONOCLOUD_AUTH_TENANT_DOMAIN;\n const MONOCLOUD_AUTH_SCOPES = process.env.MONOCLOUD_AUTH_SCOPES;\n const MONOCLOUD_AUTH_COOKIE_SECRET = process.env.MONOCLOUD_AUTH_COOKIE_SECRET;\n const MONOCLOUD_AUTH_APP_URL = process.env.MONOCLOUD_AUTH_APP_URL;\n const MONOCLOUD_AUTH_CALLBACK_URL = process.env.MONOCLOUD_AUTH_CALLBACK_URL;\n const MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL =\n process.env.MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL;\n const MONOCLOUD_AUTH_SIGNIN_URL = process.env.MONOCLOUD_AUTH_SIGNIN_URL;\n const MONOCLOUD_AUTH_SIGNOUT_URL = process.env.MONOCLOUD_AUTH_SIGNOUT_URL;\n const MONOCLOUD_AUTH_USER_INFO_URL = process.env.MONOCLOUD_AUTH_USER_INFO_URL;\n const MONOCLOUD_AUTH_RESOURCE = process.env.MONOCLOUD_AUTH_RESOURCE;\n const MONOCLOUD_AUTH_CLOCK_SKEW = process.env.MONOCLOUD_AUTH_CLOCK_SKEW;\n const MONOCLOUD_AUTH_RESPONSE_TIMEOUT =\n process.env.MONOCLOUD_AUTH_RESPONSE_TIMEOUT;\n const MONOCLOUD_AUTH_USE_PAR = process.env.MONOCLOUD_AUTH_USE_PAR;\n const MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI =\n process.env.MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI;\n const MONOCLOUD_AUTH_FEDERATED_SIGNOUT =\n process.env.MONOCLOUD_AUTH_FEDERATED_SIGNOUT;\n const MONOCLOUD_AUTH_FETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;\n const MONOCLOUD_AUTH_REFETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;\n const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES =\n process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;\n const MONOCLOUD_AUTH_SESSION_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;\n const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SECURE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_SESSION_SLIDING =\n process.env.MONOCLOUD_AUTH_SESSION_SLIDING;\n const MONOCLOUD_AUTH_SESSION_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_DURATION;\n const MONOCLOUD_AUTH_SESSION_MAX_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_MAX_DURATION;\n const MONOCLOUD_AUTH_STATE_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_NAME;\n const MONOCLOUD_AUTH_STATE_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PATH;\n const MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_STATE_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SECURE;\n const MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG =\n process.env.MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG;\n const MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS =\n process.env.MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS;\n const MONOCLOUD_AUTH_JWKS_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_JWKS_CACHE_DURATION;\n const MONOCLOUD_AUTH_METADATA_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_METADATA_CACHE_DURATION;\n\n const appUrl = options?.appUrl ?? MONOCLOUD_AUTH_APP_URL!;\n\n const opt: MonoCloudOptionsBase = {\n clientId: options?.clientId ?? MONOCLOUD_AUTH_CLIENT_ID!,\n clientSecret: options?.clientSecret ?? MONOCLOUD_AUTH_CLIENT_SECRET,\n tenantDomain: options?.tenantDomain ?? MONOCLOUD_AUTH_TENANT_DOMAIN!,\n defaultAuthParams: {\n ...(options?.defaultAuthParams ?? {}),\n scopes:\n options?.defaultAuthParams?.scopes ??\n MONOCLOUD_AUTH_SCOPES ??\n DEFAULT_OPTIONS.defaultAuthParams.scopes,\n responseType:\n options?.defaultAuthParams?.responseType ??\n (DEFAULT_OPTIONS.defaultAuthParams.responseType as any),\n resource: options?.defaultAuthParams?.resource ?? MONOCLOUD_AUTH_RESOURCE,\n },\n resources: options?.resources,\n cookieSecret: options?.cookieSecret ?? MONOCLOUD_AUTH_COOKIE_SECRET!,\n appUrl: removeTrailingSlash(appUrl),\n routes: {\n callback: removeTrailingSlash(\n options?.routes?.callback ??\n MONOCLOUD_AUTH_CALLBACK_URL ??\n DEFAULT_OPTIONS.routes.callback\n ),\n backChannelLogout: removeTrailingSlash(\n options?.routes?.backChannelLogout ??\n MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL ??\n DEFAULT_OPTIONS.routes.backChannelLogout\n ),\n signIn: removeTrailingSlash(\n options?.routes?.signIn ??\n MONOCLOUD_AUTH_SIGNIN_URL ??\n DEFAULT_OPTIONS.routes.signIn\n ),\n signOut: removeTrailingSlash(\n options?.routes?.signOut ??\n MONOCLOUD_AUTH_SIGNOUT_URL ??\n DEFAULT_OPTIONS.routes.signOut\n ),\n userInfo: removeTrailingSlash(\n options?.routes?.userInfo ??\n MONOCLOUD_AUTH_USER_INFO_URL ??\n DEFAULT_OPTIONS.routes.userInfo\n ),\n },\n clockSkew:\n options?.clockSkew ??\n getNumber(MONOCLOUD_AUTH_CLOCK_SKEW) ??\n DEFAULT_OPTIONS.clockSkew,\n responseTimeout:\n options?.responseTimeout ??\n getNumber(MONOCLOUD_AUTH_RESPONSE_TIMEOUT) ??\n DEFAULT_OPTIONS.responseTimeout,\n usePar:\n options?.usePar ??\n getBoolean(MONOCLOUD_AUTH_USE_PAR) ??\n DEFAULT_OPTIONS.usePar,\n postLogoutRedirectUri:\n options?.postLogoutRedirectUri ?? MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI,\n federatedSignOut:\n options?.federatedSignOut ??\n getBoolean(MONOCLOUD_AUTH_FEDERATED_SIGNOUT) ??\n DEFAULT_OPTIONS.federatedSignOut,\n fetchUserInfo:\n options?.fetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_FETCH_USER_INFO) ??\n DEFAULT_OPTIONS.fetchUserInfo,\n refetchUserInfo:\n options?.refetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_REFETCH_USER_INFO) ??\n DEFAULT_OPTIONS.refetchUserInfo,\n allowQueryParamOverrides:\n options?.allowQueryParamOverrides ??\n getBoolean(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ??\n DEFAULT_OPTIONS.allowQueryParamOverrides,\n session: {\n cookie: {\n name:\n options?.session?.cookie?.name ??\n MONOCLOUD_AUTH_SESSION_COOKIE_NAME ??\n DEFAULT_OPTIONS.session.cookie.name,\n path:\n options?.session?.cookie?.path ??\n MONOCLOUD_AUTH_SESSION_COOKIE_PATH ??\n DEFAULT_OPTIONS.session.cookie.path,\n domain:\n options?.session?.cookie?.domain ??\n MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN,\n httpOnly:\n options?.session?.cookie?.httpOnly ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY) ??\n DEFAULT_OPTIONS.session.cookie.httpOnly,\n secure:\n options?.session?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.session?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.session.cookie.sameSite,\n persistent:\n options?.session?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.session.cookie.persistent,\n },\n sliding:\n options?.session?.sliding ??\n getBoolean(MONOCLOUD_AUTH_SESSION_SLIDING) ??\n DEFAULT_OPTIONS.session.sliding,\n duration:\n options?.session?.duration ??\n getNumber(MONOCLOUD_AUTH_SESSION_DURATION) ??\n DEFAULT_OPTIONS.session.duration,\n maximumDuration:\n options?.session?.maximumDuration ??\n getNumber(MONOCLOUD_AUTH_SESSION_MAX_DURATION) ??\n DEFAULT_OPTIONS.session.maximumDuration,\n store: options?.session?.store,\n },\n state: {\n cookie: {\n name:\n options?.state?.cookie?.name ??\n MONOCLOUD_AUTH_STATE_COOKIE_NAME ??\n DEFAULT_OPTIONS.state.cookie.name,\n path:\n options?.state?.cookie?.path ??\n MONOCLOUD_AUTH_STATE_COOKIE_PATH ??\n DEFAULT_OPTIONS.state.cookie.path,\n domain:\n options?.state?.cookie?.domain ?? MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN,\n httpOnly: DEFAULT_OPTIONS.state.cookie.httpOnly,\n secure:\n options?.state?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.state?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.state.cookie.sameSite,\n persistent:\n options?.state?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.state.cookie.persistent,\n },\n },\n idTokenSigningAlg:\n options?.idTokenSigningAlg ??\n (MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG as SecurityAlgorithms) ??\n DEFAULT_OPTIONS.idTokenSigningAlg,\n filteredIdTokenClaims:\n options?.filteredIdTokenClaims ??\n MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS?.split(' ')\n .map(x => x.trim())\n .filter(x => x.length) ??\n DEFAULT_OPTIONS.filteredIdTokenClaims,\n debugger: options?.debugger ?? DEFAULT_OPTIONS.debugger,\n userAgent: options?.userAgent ?? DEFAULT_OPTIONS.userAgent,\n jwksCacheDuration:\n options?.jwksCacheDuration ??\n getNumber(MONOCLOUD_AUTH_JWKS_CACHE_DURATION),\n metadataCacheDuration:\n options?.metadataCacheDuration ??\n getNumber(MONOCLOUD_AUTH_METADATA_CACHE_DURATION),\n onBackChannelLogout: options?.onBackChannelLogout,\n onSetApplicationState: options?.onSetApplicationState,\n onSessionCreating: options?.onSessionCreating,\n };\n\n const { value, error } = optionsSchema.validate(opt, { abortEarly: false });\n\n const requiredEnv: Record<string, string> = {\n tenantDomain: 'MONOCLOUD_AUTH_TENANT_DOMAIN',\n clientId: 'MONOCLOUD_AUTH_CLIENT_ID',\n clientSecret: 'MONOCLOUD_AUTH_CLIENT_SECRET',\n appUrl: 'MONOCLOUD_AUTH_APP_URL',\n cookieSecret: 'MONOCLOUD_AUTH_COOKIE_SECRET',\n };\n\n if (error) {\n if (throwOnError) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n 'WARNING: One or more configuration options were not provided for MonoCloudClient.'\n );\n error.details.forEach(detail => {\n if (detail.context?.key && requiredEnv[detail.context.key]) {\n // eslint-disable-next-line no-console\n console.warn(\n `Missing: ${detail.context.key} - Set ${requiredEnv[detail.context.key]} environment variable in your .env file.`\n );\n }\n });\n }\n\n return value;\n};\n","import { createRemoteJWKSet, JWTPayload, jwtVerify } from 'jose';\nimport {\n ensureLeadingSlash,\n findToken,\n getBoolean,\n isAbsoluteUrl,\n isPresent,\n isSameHost,\n now,\n parseSpaceSeparated,\n parseSpaceSeparatedSet,\n setsEqual,\n} from '@monocloud/auth-core/internal';\nimport {\n generateNonce,\n generatePKCE,\n generateState,\n isUserInGroup,\n mergeArrays,\n parseCallbackParams,\n} from '@monocloud/auth-core/utils';\nimport type {\n Authenticators,\n AuthorizationParams,\n DisplayOptions,\n IssuerMetadata,\n MonoCloudSession,\n Prompt,\n} from '@monocloud/auth-core';\nimport {\n MonoCloudOidcClient,\n MonoCloudOPError,\n MonoCloudTokenError,\n MonoCloudValidationError,\n} from '@monocloud/auth-core';\nimport { MonoCloudSessionService } from './monocloud-session-service';\nimport { MonoCloudStateService } from './monocloud-state-service';\nimport { getOptions } from './options/get-options';\nimport {\n ApplicationState,\n CallbackOptions,\n GetTokensOptions,\n MonoCloudOptions,\n MonoCloudOptionsBase,\n MonoCloudState,\n MonoCloudTokens,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from './types';\nimport {\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n MonoCloudRequest,\n MonoCloudResponse,\n} from './types/internal';\nimport {\n callbackOptionsSchema,\n getTokensOptionsSchema,\n resourceValidationSchema,\n scopesValidationSchema,\n signInOptionsSchema,\n signOutOptionsSchema,\n userInfoOptionsSchema,\n} from './options/validation';\nimport dbug, { Debugger } from 'debug';\n\n/**\n * @category Classes\n */\nexport class MonoCloudCoreClient {\n public readonly oidcClient: MonoCloudOidcClient;\n\n private readonly options: MonoCloudOptionsBase;\n\n private readonly stateService: MonoCloudStateService;\n\n private readonly sessionService: MonoCloudSessionService;\n\n private readonly debug: Debugger;\n\n private optionsValidated = false;\n\n constructor(partialOptions?: MonoCloudOptions) {\n this.options = getOptions(partialOptions, false);\n this.oidcClient = new MonoCloudOidcClient(\n this.options.tenantDomain,\n this.options.clientId,\n {\n clientSecret: this.options.clientSecret,\n idTokenSigningAlgorithm: this.options.idTokenSigningAlg,\n }\n );\n this.debug = dbug(this.options.debugger);\n this.stateService = new MonoCloudStateService(this.options);\n this.sessionService = new MonoCloudSessionService(this.options);\n\n /* v8 ignore next -- @preserve */\n if (process.env.DEBUG && !this.debug.enabled) {\n dbug.enable(process.env.DEBUG);\n }\n\n this.debug('Debug logging enabled.');\n }\n\n /**\n * Initiates the sign-in flow by redirecting the user to the MonoCloud authorization endpoint.\n *\n * This method handles scope and resource merging, state generation (nonce, state, PKCE),\n * and constructing the final authorization URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signInOptions - Configuration to customize the sign-in behavior.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} When validation of parameters or state fails.\n */\n async signIn(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signInOptions?: SignInOptions\n ): Promise<any> {\n this.debug('Starting sign-in handler');\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const indicatorResource = this.options.resources\n ?.map(x => x.resource)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n const indicatorScopes = this.options.resources\n ?.map(x => x.scopes)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n\n const mergedScopes = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.scopes),\n parseSpaceSeparated(this.options.defaultAuthParams.scopes),\n parseSpaceSeparated(indicatorScopes)\n ) ?? ['openid'];\n\n const mergedResources = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.resource),\n parseSpaceSeparated(this.options.defaultAuthParams.resource),\n parseSpaceSeparated(indicatorResource)\n );\n\n // Merge the sign-in options and the default options\n const opt = {\n ...(signInOptions ?? {}),\n authParams: {\n ...this.options.defaultAuthParams,\n ...signInOptions?.authParams,\n scopes: mergedScopes.join(' '),\n acrValues: mergeArrays(\n signInOptions?.authParams?.acrValues,\n this.options.defaultAuthParams.acrValues\n ),\n resource: mergedResources?.join(' '),\n },\n };\n\n let appState: ApplicationState = {};\n\n // Set the application state if the onSetApplicationState function is set\n if (this.options.onSetApplicationState) {\n appState = await this.options.onSetApplicationState(request);\n\n // Validate the custom sign-in state\n if (\n appState === null ||\n appState === undefined ||\n typeof appState !== 'object' ||\n Array.isArray(appState)\n ) {\n throw new MonoCloudValidationError(\n 'Invalid Application State. Expected state to be an object'\n );\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n returnUrl: request.getQuery('return_url') as string,\n authenticatorHint: request.getQuery(\n 'authenticator_hint'\n ) as Authenticators,\n scope: request.getQuery('scope') as string,\n resource: request.getQuery('resource') as string,\n display: request.getQuery('display') as DisplayOptions,\n uiLocales: request.getQuery('ui_locales') as string,\n acrValues: request.getQuery('acr_values') as string,\n loginHint: request.getQuery('login_hint') as string,\n prompt: request.getQuery('prompt') as Prompt,\n maxAge: parseInt(request.getQuery('max_age') as string, 10),\n }\n : {};\n\n // Set the return url if passed down\n const retUrl = query.returnUrl ?? opt.returnUrl;\n if (\n typeof retUrl === 'string' &&\n retUrl &&\n (!isAbsoluteUrl(retUrl) || isSameHost(this.options.appUrl, retUrl))\n ) {\n opt.returnUrl = retUrl;\n }\n\n // Validate the options\n const { error } = signInOptionsSchema.validate(opt, { abortEarly: true });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // Generate the state, nonce & code verifier\n const state = generateState();\n const nonce = generateNonce();\n const { codeChallenge, codeVerifier } = await generatePKCE();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (!isNaN(query.maxAge!)) {\n opt.authParams.maxAge = query.maxAge;\n }\n\n // Ensure that return to is present, if not then use the base url as the return to\n const returnUrl = encodeURIComponent(\n opt.returnUrl ?? this.options.appUrl\n );\n\n const redirectUrl = `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n // Create the Authorization Parameters\n let params: AuthorizationParams = {\n redirectUri: redirectUrl,\n ...opt.authParams,\n nonce,\n state,\n codeChallenge,\n };\n\n // Set the Authenticator if passed down\n const authenticatorHint =\n query.authenticatorHint ?? opt.authParams.authenticatorHint;\n if (typeof authenticatorHint === 'string' && authenticatorHint) {\n params.authenticatorHint = authenticatorHint;\n }\n\n const scopes =\n (typeof query.scope === 'string' ? query.scope : undefined) ??\n opt.authParams.scopes;\n\n if (scopes) {\n const { error: e } = scopesValidationSchema.validate(scopes, {\n abortEarly: true,\n });\n\n if (!e) {\n params.scopes = scopes;\n }\n }\n\n const resource =\n (typeof query.resource === 'string' ? query.resource : undefined) ??\n opt.authParams.resource;\n\n // Set the resources mode if passed down\n if (resource) {\n const { error: e } = resourceValidationSchema.validate(resource, {\n abortEarly: true,\n });\n\n if (!e) {\n params.resource = resource;\n }\n }\n\n // Set the display if passed down\n const display = query.display ?? opt.authParams.display;\n if (typeof display === 'string' && display) {\n params.display = display as unknown as DisplayOptions;\n }\n\n // Set the ui locales if passed down\n const uiLocales = query.uiLocales ?? opt.authParams.uiLocales;\n if (typeof uiLocales === 'string' && uiLocales) {\n params.uiLocales = uiLocales;\n }\n\n // Set the acr values if passed down\n const acrValues = query.acrValues ?? opt.authParams.acrValues;\n if (typeof acrValues === 'string' && acrValues) {\n params.acrValues = acrValues\n .split(' ')\n .map(x => x.trim())\n .filter(x => x !== '');\n }\n\n // Set the login hint if passed down\n const loginHint = query.loginHint ?? opt.authParams.loginHint;\n if (typeof loginHint === 'string' && loginHint) {\n params.loginHint = loginHint;\n }\n\n // Set the prompt if passed down\n let prompt: string | undefined;\n if (typeof query.prompt === 'string') {\n prompt = query.prompt;\n } else {\n prompt = opt.register ? 'create' : opt.authParams.prompt;\n }\n\n if (prompt) {\n params.prompt = prompt as Prompt;\n }\n\n /* v8 ignore next -- @preserve */\n if (!params.scopes || params.scopes.length < 0) {\n throw new MonoCloudValidationError(\n 'Scopes are required for signing in'\n );\n }\n\n // Generate the monocloud state\n const monoCloudState: MonoCloudState = {\n returnUrl,\n state,\n nonce,\n codeVerifier,\n maxAge: opt.authParams.maxAge,\n appState: JSON.stringify(appState),\n resource: this.options.defaultAuthParams.resource,\n scopes: params.scopes,\n };\n\n if (this.options.usePar) {\n const { request_uri } =\n await this.oidcClient.pushedAuthorizationRequest(params);\n\n params = {\n requestUri: request_uri,\n };\n }\n\n // Create authorize url\n const authUrl = await this.oidcClient.authorizationUrl(params);\n\n // Set the state cookie\n await this.stateService.setState(\n response,\n monoCloudState,\n params.responseMode === 'form_post' ? 'none' : undefined\n );\n // Redirect to authorize url\n response.redirect(authUrl, 302);\n } catch (error) {\n if (typeof signInOptions?.onError === 'function') {\n return signInOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles the OpenID callback after the user authenticates with MonoCloud.\n *\n * Processes the authorization code, validates the state and nonce, exchanges the code for tokens,\n * initializes the user session, and performs the final redirect to the application's return URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param callbackOptions - Optional configuration for the callback handler.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} If the state is mismatched or tokens are invalid.\n */\n async callback(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n callbackOptions?: CallbackOptions\n ): Promise<any> {\n this.debug('Starting callback handler');\n\n try {\n this.validateOptions();\n\n const { method, url, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get' && method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the callback Options\n if (callbackOptions) {\n const { error } = callbackOptionsSchema.validate(callbackOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the state value\n const monoCloudState = await this.stateService.getState(\n request,\n response\n );\n\n // Handle invalid state\n if (!monoCloudState) {\n throw new MonoCloudValidationError('Invalid Authentication State');\n }\n\n let fullUrl = url;\n\n // check if the url is a relative url\n if (!isAbsoluteUrl(url)) {\n fullUrl = `${this.options.appUrl}${ensureLeadingSlash(url)}`;\n }\n\n // Get the search parameters or the body\n const payload =\n method.toLowerCase() === 'post'\n ? new URLSearchParams(body)\n : new URL(fullUrl).searchParams;\n\n // Get the parameters returned from the server\n const callbackParams = parseCallbackParams(payload);\n\n if (callbackParams.state !== monoCloudState.state) {\n throw new MonoCloudValidationError('Invalid state');\n }\n\n if (isPresent(callbackParams.error)) {\n throw new MonoCloudOPError(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n callbackParams.error!,\n callbackParams.errorDescription\n );\n }\n\n // Get the redirect Url to be validated\n const redirectUri =\n callbackOptions?.redirectUri ??\n `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n if (!callbackParams.code) {\n throw new MonoCloudValidationError(\n 'Authorization code not found in callback params'\n );\n }\n\n // Parse the client state\n const appState: ApplicationState = JSON.parse(monoCloudState.appState);\n\n const session = await this.oidcClient.authenticate(\n callbackParams.code,\n redirectUri,\n monoCloudState.scopes,\n monoCloudState.resource,\n {\n codeVerifier: monoCloudState.codeVerifier,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenNonce: monoCloudState.nonce,\n idTokenMaxAge: monoCloudState.maxAge,\n idTokenClockTolerance: 5,\n fetchUserInfo:\n callbackOptions?.fetchUserInfo ?? this.options.fetchUserInfo,\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: async (s, i, u) =>\n await this.options.onSessionCreating?.(s, i, u, appState),\n }\n );\n\n // Set the user session\n await this.sessionService.setSession(request, response, session);\n\n // Return to base url if no return url was set\n if (!monoCloudState.returnUrl) {\n response.redirect(this.options.appUrl);\n return response.done();\n }\n\n // Return to a valid return to url\n try {\n const decodedUrl = decodeURIComponent(monoCloudState.returnUrl);\n\n if (!isAbsoluteUrl(decodedUrl)) {\n response.redirect(\n `${this.options.appUrl}${ensureLeadingSlash(decodedUrl)}`\n );\n return response.done();\n }\n\n if (isSameHost(this.options.appUrl, decodedUrl)) {\n response.redirect(decodedUrl);\n return response.done();\n }\n } catch {\n // do nothing\n }\n\n response.redirect(this.options.appUrl);\n } catch (error) {\n if (typeof callbackOptions?.onError === 'function') {\n return callbackOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Retrieves user information, optionally refetching fresh data from the UserInfo endpoint.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param userinfoOptions - Configuration to control refetching and error handling.\n * @returns A promise that resolves with the user information sent as a JSON response.\n *\n * @remarks\n * If `refresh` is true, the session is updated with fresh claims from the identity provider.\n */\n async userInfo(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n userinfoOptions?: UserInfoOptions\n ): Promise<any> {\n this.debug('Starting userinfo handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the User Info options\n if (userinfoOptions) {\n const { error } = userInfoOptionsSchema.validate(userinfoOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? { refresh: getBoolean(request.getQuery('refresh') as string) }\n : {};\n\n const refetchUserInfo =\n query.refresh ??\n userinfoOptions?.refresh ??\n this.options.refetchUserInfo;\n\n // Get the user session\n const session = await this.sessionService.getSession(\n request,\n response,\n !refetchUserInfo\n );\n\n // Handle no session\n if (!session) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n const defaultToken = findToken(\n session.accessTokens,\n this.options.defaultAuthParams.resource,\n session.authorizedScopes\n );\n\n // If refetch is false then return the session\n if (!refetchUserInfo || !defaultToken) {\n response.sendJson(session.user);\n return response.done();\n }\n\n // Get the new session\n const newSession = await this.oidcClient.refetchUserInfo(\n defaultToken,\n session,\n {\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n }\n );\n\n // Update the session containing the new claims\n const updated = await this.sessionService.updateSession(\n request,\n response,\n newSession\n );\n\n // Handle session was not updated successfully\n if (!updated) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n // Return the Claims\n response.sendJson(session.user);\n } catch (error) {\n if (typeof userinfoOptions?.onError === 'function') {\n return userinfoOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Initiates the sign-out flow, destroying the local session and optionally performing federated sign-out.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signOutOptions - Configuration for post-logout behavior and federated sign-out.\n *\n * @returns A promise that resolves when the sign-out redirection is initiated.\n */\n async signOut(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signOutOptions?: SignOutOptions\n ): Promise<any> {\n this.debug('Starting sign-out handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the sign-out options\n if (signOutOptions) {\n const { error } = signOutOptionsSchema.validate(signOutOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n postLogoutUrl: request.getQuery('post_logout_url') as string,\n federated: getBoolean(request.getQuery('federated') as string),\n }\n : {};\n\n // Build the return to url\n let returnUrl =\n this.options.postLogoutRedirectUri ??\n signOutOptions?.postLogoutRedirectUri ??\n this.options.appUrl;\n\n // Set the return url if passed down\n if (query.postLogoutUrl) {\n const { error } = signOutOptionsSchema.validate({\n postLogoutRedirectUri: query.postLogoutUrl,\n });\n\n if (!error) {\n returnUrl = query.postLogoutUrl;\n }\n }\n\n // Ensure the return to is an absolute one\n if (!isAbsoluteUrl(returnUrl)) {\n returnUrl = `${this.options.appUrl}${ensureLeadingSlash(returnUrl)}`;\n }\n\n // Get the current session\n const session = await this.sessionService.getSession(\n request,\n response,\n false\n );\n\n // Redirect to return url if session doesn't exist\n if (!session) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n await this.sessionService.removeSession(request, response);\n\n // Handle Federated Sign Out\n const isFederatedSignOut =\n query.federated ??\n signOutOptions?.federatedSignOut ??\n this.options.federatedSignOut;\n\n if (!isFederatedSignOut) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n // Build the end session Url\n const url = await this.oidcClient.endSessionUrl({\n idToken: session.idToken,\n postLogoutRedirectUri: returnUrl,\n state: signOutOptions?.state,\n });\n\n // Redirect the user to the end session endpoint\n response.redirect(url);\n } catch (error) {\n if (typeof signOutOptions?.onError === 'function') {\n return signOutOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles Back-Channel Logout notifications from the identity provider.\n *\n * Validates the Logout Token and triggers the `onBackChannelLogout` callback defined in options.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n *\n * @returns A promise that resolves when the logout notification has been processed.\n *\n * @throws {@link MonoCloudValidationError} If the logout token is missing or invalid.\n */\n async backChannelLogout(\n request: MonoCloudRequest,\n response: MonoCloudResponse\n ): Promise<any> {\n this.debug('Starting back-channel logout handler');\n\n try {\n this.validateOptions();\n\n response.setNoCache();\n\n if (!this.options.onBackChannelLogout) {\n response.notFound();\n return response.done();\n }\n\n const { method, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const params = new URLSearchParams(body);\n const logoutToken = params.get('logout_token');\n\n if (!logoutToken) {\n throw new MonoCloudValidationError('Missing Logout Token');\n }\n\n const metadata = await this.oidcClient.getMetadata();\n\n const { sid, sub } = await this.verifyLogoutToken(logoutToken, metadata);\n\n await this.options.onBackChannelLogout(sub, sid as any);\n\n response.noContent();\n } catch (error) {\n this.handleCatchAll(error as Error, response);\n }\n\n return response.done();\n }\n\n /**\n * Checks if the current request has an active and authenticated session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @returns `true` if a valid session with user data exists, `false` otherwise.\n *\n */\n async isAuthenticated(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<boolean> {\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n // Return true if the session exists\n return !!session?.user;\n }\n\n /**\n * Checks if the current session user belongs to the specified groups.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param groups - List of group names or IDs to check.\n * @param groupsClaim - Optional claim name that holds groups. Defaults to \"groups\".\n * @param matchAll - If `true`, requires membership in all groups; otherwise any one group is sufficient.\n *\n * @returns `true` if the user satisfies the group condition, `false` otherwise.\n */\n async isUserInGroup(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n groups: string[],\n groupsClaim?: string,\n matchAll?: boolean\n ): Promise<boolean> {\n const session = await this.sessionService.getSession(request, response);\n\n if (!session?.user) {\n return false;\n }\n\n return isUserInGroup(session.user, groups, groupsClaim, matchAll);\n }\n\n /**\n * Retrieves the current user's session data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @returns Session or `undefined`.\n */\n getSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<MonoCloudSession | undefined> {\n return this.sessionService.getSession(request, response);\n }\n\n /**\n * Updates the current user's session with new data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param session - The updated session object to persist.\n */\n async updateSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<void> {\n await this.sessionService.updateSession(request, response, session);\n }\n\n /**\n * Returns a copy of the current client configuration options.\n *\n * @returns A copy of the initialized configuration.\n */\n getOptions(): MonoCloudOptionsBase {\n return { ...this.options };\n }\n\n /**\n * Destroys the local user session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @remarks\n * This does not perform federated sign-out. For identity provider sign-out, use `signOut` handler.\n */\n destroySession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<void> {\n return this.sessionService.removeSession(request, response);\n }\n\n /**\n * Retrieves active tokens (Access, ID, Refresh), performing a refresh if they are expired or missing.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param options - Configuration for token retrieval (force refresh, specific scopes/resources).\n *\n * @returns Fetched tokens.\n *\n * @throws {@link MonoCloudValidationError} If the session does not exist or tokens cannot be found/refreshed.\n */\n async getTokens(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n options?: GetTokensOptions\n ): Promise<MonoCloudTokens> {\n // Validate the get tokens options\n if (options) {\n const { error } = getTokensOptionsSchema.validate(options, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n if (!session) {\n throw new MonoCloudValidationError('Session does not exist');\n }\n\n let scopes = options?.scopes;\n\n const resource =\n options?.resource ?? this.options.defaultAuthParams.resource;\n\n if (isPresent(options?.resource)) {\n if (!isPresent(scopes)) {\n // Check if there is a resource with undefined scope\n const noScopeResource = this.options.resources?.find(\n x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n ) && !x.scopes\n );\n\n // Search for the same resource with scopes defined\n if (!noScopeResource) {\n scopes = this.options.resources?.find(x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n )\n )?.scopes;\n }\n }\n }\n\n const findTokenScopes =\n !isPresent(options?.resource) && !isPresent(scopes)\n ? session.authorizedScopes\n : scopes;\n\n let token = findToken(session.accessTokens, resource, findTokenScopes);\n\n const tokenExpired = !!token && token.accessTokenExpiration - 30 < now();\n\n let { idToken } = session;\n let { refreshToken } = session;\n\n if (options?.forceRefresh || !token || tokenExpired) {\n if (!refreshToken && token && tokenExpired) {\n throw new MonoCloudTokenError(\n 'No refresh token available to refresh the expired access token'\n );\n }\n\n const updatedSession = await this.oidcClient.refreshSession(session, {\n fetchUserInfo: options?.refetchUserInfo ?? this.options.refetchUserInfo,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenClockTolerance: 5,\n refreshGrantOptions: {\n resource,\n scopes,\n },\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n });\n\n await this.sessionService.updateSession(\n request,\n response,\n updatedSession\n );\n\n token = findToken(\n updatedSession?.accessTokens,\n resource,\n findTokenScopes\n );\n\n idToken = updatedSession.idToken;\n refreshToken = updatedSession.refreshToken;\n }\n\n // Just in case. At this point, the access token should be present\n /* v8 ignore next -- @preserve */\n if (!token) {\n throw new MonoCloudValidationError('Access token not found');\n }\n\n return {\n ...token,\n idToken,\n refreshToken,\n isExpired: token.accessTokenExpiration - 30 < now(),\n };\n }\n\n private async verifyLogoutToken(\n token: string,\n metadata: IssuerMetadata\n ): Promise<JWTPayload> {\n const jwks = createRemoteJWKSet(new URL(metadata.jwks_uri));\n\n const { payload } = await jwtVerify(token, jwks, {\n issuer: metadata.issuer,\n audience: this.options.clientId,\n algorithms: [this.options.idTokenSigningAlg],\n requiredClaims: ['iat'],\n });\n\n if (\n (!payload.sid && !payload.sub) ||\n payload.nonce ||\n !payload.events ||\n typeof payload.events !== 'object'\n ) {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n const event = (payload.events as any)[\n 'http://schemas.openid.net/event/backchannel-logout'\n ];\n\n if (!event || typeof event !== 'object') {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n return payload;\n }\n\n private handleCatchAll(error: Error, res: MonoCloudResponse): void {\n // eslint-disable-next-line no-console\n console.error(error);\n res.internalServerError();\n }\n\n private validateOptions(): void {\n if (!this.optionsValidated) {\n this.optionsValidated = true;\n getOptions(this.options);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["uuid","MonoCloudValidationError","MonoCloudValidationError","MonoCloudOPError","MonoCloudTokenError"],"sources":["../src/monocloud-session-service.ts","../src/monocloud-state-service.ts","../src/options/defaults.ts","../src/options/validation.ts","../src/options/get-options.ts","../src/monocloud-node-core-client.ts"],"sourcesContent":["import { v4 as uuid } from 'uuid';\nimport { serialize } from 'cookie';\nimport { decrypt, encrypt } from '@monocloud/auth-core/utils';\nimport type { MonoCloudSession, MonoCloudUser } from '@monocloud/auth-core';\nimport { now } from '@monocloud/auth-core/internal';\nimport { MonoCloudOptionsBase } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n SessionCookieValue,\n} from './types/internal';\n\nconst CHUNK_BYTE_SIZE = 4090;\n\nexport class MonoCloudSessionService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<string> {\n // Generate a session Id\n const key = uuid();\n\n // Set the issued and updated time\n const iat = now();\n const uat = iat;\n\n // Calculate the lifetime of the cookie\n const exp = this.getExpiry(iat, uat);\n\n // Set the Cookie Value\n const cookieValue: SessionCookieValue = {\n key,\n lifetime: { c: iat, u: uat, e: exp },\n };\n\n // Save the Session\n await this.saveSession(req, res, cookieValue, session);\n\n // Return the session Id\n return key;\n }\n\n async getSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n shouldResave = true\n ): Promise<MonoCloudSession | undefined> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return undefined;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // if there is no session store\n if (!this.options.session.store) {\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n\n // ensure that the cookie has a session\n if (!cookieValue.session) {\n return undefined;\n }\n\n // create a session object\n Object.assign(session, JSON.parse(JSON.stringify(cookieValue.session)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n // Get the session from the store\n const sessionObj = await this.options.session.store.get(cookieValue.key);\n\n // if there is no session in the store then delete the cookie\n if (!sessionObj) {\n await this.deleteAllCookies(req, res);\n return undefined;\n }\n\n // Get the instance of the session\n const session: MonoCloudSession = { user: {} as MonoCloudUser };\n Object.assign(session, JSON.parse(JSON.stringify(sessionObj)));\n\n // Resave the session if the new expiry is different from the old one\n if (shouldResave && exp !== cookieValue.lifetime.e) {\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n }\n\n // return the sesison\n return session;\n }\n\n async updateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<boolean> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return false;\n }\n\n // Ensure that the session is valid\n const isValid = await this.validateSession(req, res, cookieValue);\n\n // Handle an invalid session\n if (!isValid) {\n return false;\n }\n\n // Get the new expiry for the cookie\n const uat = now();\n const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n // Save the session\n await this.saveSession(\n req,\n res,\n {\n ...cookieValue,\n lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n },\n session\n );\n\n return true;\n }\n\n async removeSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n // Get the current cookie value\n const cookieValue = await this.getCookieData(req);\n\n // Handle no cookie value\n if (!cookieValue) {\n await this.deleteAllCookies(req, res);\n return;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Delete the current session from the store\n /* v8 ignore else -- @preserve */\n if (cookieValue.key) {\n await this.options.session.store.delete(cookieValue.key);\n }\n }\n\n await this.deleteAllCookies(req, res);\n }\n\n private async validateSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue\n ): Promise<boolean> {\n // Get the current time\n const nowTime = now();\n\n let isValid = true;\n\n // Ensure that the expiration has not passed\n if (cookieValue.lifetime.e && cookieValue.lifetime.e < nowTime) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not expired based on the last updated time\n if (\n this.options.session.sliding &&\n cookieValue.lifetime.u + this.options.session.duration < nowTime\n ) {\n isValid = false;\n }\n\n // If the session is sliding then ensure that the session has not crossed the maximum duration allowed\n if (\n cookieValue.lifetime.c + this.options.session.maximumDuration <\n nowTime\n ) {\n isValid = false;\n }\n\n // return Is Valid if all ok\n if (isValid) {\n return true;\n }\n\n // If there is a session store then delete the session from the store\n if (this.options.session.store) {\n await this.options.session.store.delete(cookieValue.key);\n }\n\n await this.deleteAllCookies(req, res);\n\n return false;\n }\n\n private async saveSession(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse,\n cookieValue: SessionCookieValue,\n session: MonoCloudSession\n ): Promise<void> {\n const cookies = new Set((await this.getRequestCookie(req))?.keys ?? []);\n\n // If no session store is present\n if (!this.options.session.store) {\n // Set the cookie session Value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = session;\n }\n\n // If session store is present\n if (this.options.session.store) {\n // Get the cookie containing the session Id\n const cookieData = await this.getCookieData(req);\n\n // Delete the current session from the store\n if (cookieData?.key) {\n await this.options.session.store.delete(cookieData.key);\n }\n\n // Ensure there is no session in the cookie value\n // eslint-disable-next-line no-param-reassign\n cookieValue.session = undefined;\n\n // Set the new session in the store\n await this.options.session.store.set(\n cookieValue.key,\n session,\n cookieValue.lifetime\n );\n }\n\n // Encrypt the cookie value\n const encryptedData = await encrypt(\n JSON.stringify(cookieValue),\n this.options.cookieSecret\n );\n\n const cookieExpiry = cookieValue.lifetime.e\n ? new Date(cookieValue.lifetime.e * 1000)\n : undefined;\n\n const cookieOptions = this.getCookieOptions(cookieExpiry);\n const chunkSize =\n CHUNK_BYTE_SIZE -\n serialize(`${this.options.session.cookie.name}.0`, '', cookieOptions)\n .length;\n\n // Calculate the number of cookie chunks\n const chunks = Math.ceil(encryptedData.length / chunkSize);\n\n for (let i = 0; i < chunks; i += 1) {\n const encryptedChunk = encryptedData.slice(\n i * chunkSize,\n (i + 1) * chunkSize\n );\n\n const cookieName =\n chunks === 1\n ? this.options.session.cookie.name\n : `${this.options.session.cookie.name}.${i}`;\n\n await res.setCookie(\n cookieName,\n encryptedChunk,\n this.getCookieOptions(cookieExpiry)\n );\n\n cookies.delete(cookieName);\n }\n\n // Delete all cookies which are not required anymore\n for (const cookie of cookies) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n\n private async getCookieData(\n req: IMonoCloudCookieRequest\n ): Promise<SessionCookieValue | undefined> {\n // Get all the cookies\n const cookieData = await this.getRequestCookie(req);\n\n // Handle no cookies\n if (!cookieData?.value) {\n return undefined;\n }\n\n // Decrypt the cookie\n const data = await decrypt(cookieData.value, this.options.cookieSecret);\n\n // Handle no data\n if (!data) {\n return undefined;\n }\n\n // Return the parsed session cookie value\n return JSON.parse(data);\n }\n\n private async getRequestCookie(\n req: IMonoCloudCookieRequest\n ): Promise<{ keys: string[]; value: string } | undefined> {\n // Get all the cookies\n const cookies = await req.getAllCookies();\n\n // Handle no cookies\n if (!cookies.size) {\n return undefined;\n }\n\n // If a cookie exists without chunks then return it\n const val = cookies.get(this.options.session.cookie.name);\n\n if (val) {\n return { keys: [this.options.session.cookie.name], value: val };\n }\n\n // Filter out the cookies and only keep the relevant ones\n const cookieValues = Array.from(cookies.entries())\n .filter(([cookie]) =>\n cookie.startsWith(`${this.options.session.cookie.name}.`)\n )\n .map(([cookie, value]) => ({\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n key: parseInt(cookie.split('.').pop() || '0', 10),\n value,\n }))\n .sort((a, b) => a.key - b.key);\n\n // Sort the cookies by chunk numbers\n const cookieValue = cookieValues.map(({ value }) => value).join('');\n\n // Handle empty cookie value\n if (!cookieValue) {\n return undefined;\n }\n\n // Return the cookie names and values\n return {\n keys: cookieValues.map(\n ({ key }) => `${this.options.session.cookie.name}.${key}`\n ),\n value: cookieValue,\n };\n }\n\n private getExpiry(iat: number, uat: number): number | undefined {\n // Return null if session is not persistent\n if (!this.options.session.cookie.persistent) {\n return undefined;\n }\n\n // If session is not sliding the return the absolute expiration\n if (!this.options.session.sliding) {\n return Math.floor(iat + this.options.session.duration);\n }\n\n // If session is sliding then return the lesser of the next extended time or the maximum duration\n return Math.floor(\n Math.min(\n uat + this.options.session.duration,\n iat + this.options.session.maximumDuration\n )\n );\n }\n\n private getCookieOptions(exp?: Date): CookieOptions {\n return {\n domain: this.options.session.cookie.domain,\n httpOnly: this.options.session.cookie.httpOnly,\n sameSite: this.options.session.cookie.sameSite,\n secure: this.options.session.cookie.secure,\n path: this.options.session.cookie.path,\n expires: exp,\n };\n }\n\n private async deleteAllCookies(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<void> {\n const reqCookie = await this.getRequestCookie(req);\n\n const cookies = reqCookie?.keys?.filter(x =>\n x.startsWith(this.options.session.cookie.name)\n );\n\n for (const cookie of cookies ?? []) {\n await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n }\n }\n}\n","import { decryptAuthState, encryptAuthState } from '@monocloud/auth-core/utils';\nimport { MonoCloudOptionsBase, MonoCloudState, SameSiteValues } from './types';\nimport {\n CookieOptions,\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n} from './types/internal';\n\nexport class MonoCloudStateService {\n constructor(private readonly options: MonoCloudOptionsBase) {}\n\n async setState(\n res: IMonoCloudCookieResponse,\n state: MonoCloudState,\n overrideSameSite?: SameSiteValues\n ): Promise<void> {\n await res.setCookie(\n this.options.state.cookie.name,\n await encryptAuthState(state, this.options.cookieSecret),\n this.getCookieOptions(overrideSameSite)\n );\n }\n\n async getState(\n req: IMonoCloudCookieRequest,\n res: IMonoCloudCookieResponse\n ): Promise<MonoCloudState | undefined> {\n // Get the cookie\n const cookie = await req.getCookie(this.options.state.cookie.name);\n\n // Handle no cookie\n if (!cookie) {\n return undefined;\n }\n\n let decryptedResult: MonoCloudState;\n\n try {\n // Decrypt the cookie value\n decryptedResult = await decryptAuthState(\n cookie,\n this.options.cookieSecret\n );\n } catch {\n return undefined;\n }\n\n // Remove the cookie\n await res.setCookie(this.options.state.cookie.name, '', {\n ...this.getCookieOptions(),\n expires: new Date(0),\n });\n\n // return the state\n return decryptedResult;\n }\n\n private getCookieOptions(sameSite?: SameSiteValues): CookieOptions {\n return {\n domain: this.options.state.cookie.domain,\n httpOnly: this.options.state.cookie.httpOnly,\n sameSite: sameSite ?? this.options.state.cookie.sameSite,\n secure: this.options.state.cookie.secure,\n path: this.options.state.cookie.path,\n };\n }\n}\n","export const DEFAULT_OPTIONS = {\n routes: {\n callback: '/api/auth/callback',\n backChannelLogout: '/api/auth/backchannel-logout',\n signIn: '/api/auth/signin',\n signOut: '/api/auth/signout',\n userInfo: '/api/auth/userinfo',\n },\n clockSkew: 60,\n responseTimeout: 10000,\n usePar: false,\n fetchUserInfo: true,\n refetchUserInfo: false,\n federatedSignOut: true,\n defaultAuthParams: {\n scopes: 'openid profile email',\n responseType: 'code',\n },\n allowQueryParamOverrides: true,\n strictProfileSync: false,\n session: {\n cookie: {\n httpOnly: true,\n name: 'session',\n path: '/',\n sameSite: 'lax',\n persistent: true,\n },\n sliding: false,\n duration: 24 * 60 * 60,\n maximumDuration: 7 * 24 * 60 * 60,\n },\n state: {\n cookie: {\n httpOnly: true,\n name: 'state',\n path: '/',\n sameSite: 'lax',\n persistent: false,\n },\n },\n idTokenSigningAlg: 'RS256',\n filteredIdTokenClaims: [\n 'iss',\n 'exp',\n 'nbf',\n 'aud',\n 'nonce',\n 'iat',\n 'auth_time',\n 'c_hash',\n 'at_hash',\n 's_hash',\n ],\n debugger: 'node-auth-core',\n userAgent: 'node-auth-core',\n};\n","import Joi from 'joi';\nimport type { AuthorizationParams } from '@monocloud/auth-core';\nimport {\n CallbackOptions,\n GetSessionOptions,\n GetTokensOptions,\n Indicator,\n MonoCloudOptionsBase,\n MonoCloudRoutes,\n MonoCloudSessionOptionsBase,\n MonoCloudStateOptions,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from '../types';\n\nconst stringRequired = Joi.string().required();\nconst stringOptional = Joi.string().optional();\nconst boolRequired = Joi.boolean().required();\nconst boolOptional = Joi.boolean().optional();\nconst numRequired = Joi.number().required();\nconst numOptional = Joi.number().optional();\nconst objectOptional = Joi.object().optional();\nconst funcOptional = Joi.function().optional();\n\nconst sessionCookieSchema = Joi.object({\n name: stringRequired,\n path: stringRequired.uri({ relativeOnly: true }),\n domain: stringOptional,\n httpOnly: boolRequired,\n secure: boolRequired.when(Joi.ref('/appUrl'), {\n is: Joi.string().pattern(/^https:/i),\n then: Joi.valid(true).messages({\n 'any.only':\n 'Cookie must be set to secure when app url protocol is https.',\n }),\n otherwise: Joi.valid(false),\n }),\n sameSite: stringRequired.valid('strict', 'lax', 'none'),\n persistent: boolRequired,\n}).required();\n\nconst resourceSchema = stringRequired.custom((value, helpers) => {\n let valid: boolean;\n try {\n const url = new URL(value);\n valid = url.searchParams.size === 0 && url.hash.length === 0;\n } catch {\n valid = false;\n }\n\n if (!valid) {\n return helpers.message({\n custom: 'Resource must be a valid URL without query or hash parameters',\n });\n }\n\n return value;\n});\n\nexport const resourceValidationSchema = Joi.string()\n .custom((value, helpers) => {\n const parts = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (parts.length === 0) {\n return helpers.message({ custom: 'Resource must not be empty' });\n }\n\n for (const part of parts) {\n const { error } = resourceSchema.validate(part);\n if (error) {\n return helpers.message({\n custom: `Invalid resource \"${part}\": ${error.message}`,\n });\n }\n }\n\n return parts.join(' ');\n })\n .messages({\n 'string.base': 'Resource must be a space-separated string of URLs',\n });\n\nconst sessionSchema: Joi.ObjectSchema<MonoCloudSessionOptionsBase> = Joi.object(\n {\n cookie: sessionCookieSchema,\n sliding: boolRequired,\n duration: numRequired.min(1),\n maximumDuration: numRequired.min(1).greater(Joi.ref('duration')),\n store: objectOptional,\n }\n).required();\n\nconst stateSchema: Joi.ObjectSchema<MonoCloudStateOptions> = Joi.object({\n cookie: sessionCookieSchema,\n}).required();\n\nconst scopesSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n if (!scopes.includes('openid')) {\n return helpers.message({ custom: 'Scope must contain openid' });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nconst authParamSchema: Joi.ObjectSchema<AuthorizationParams> = Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n resource: resourceValidationSchema.optional(),\n})\n .unknown(true)\n .required();\n\nconst optionalAuthParamSchema: Joi.ObjectSchema<AuthorizationParams> =\n Joi.object({\n scopes: scopesSchema,\n responseType: stringOptional.valid('code').optional(),\n responseMode: stringOptional.valid('query', 'form_post'),\n })\n .unknown(true)\n .optional();\n\nconst routesSchema: Joi.ObjectSchema<MonoCloudRoutes> = Joi.object({\n callback: stringRequired.uri({ relativeOnly: true }),\n backChannelLogout: stringRequired.uri({ relativeOnly: true }),\n signIn: stringRequired.uri({ relativeOnly: true }),\n signOut: stringRequired.uri({ relativeOnly: true }),\n userInfo: stringRequired.uri({ relativeOnly: true }),\n}).required();\n\nexport const scopesValidationSchema = stringRequired\n .custom((value, helpers) => {\n const scopes = value\n .split(/\\s+/)\n .map((x: string) => x.trim())\n .filter(Boolean);\n\n if (scopes.length === 0) {\n return helpers.message({\n custom: 'Scopes must be a space-separated string',\n });\n }\n\n return scopes.join(' ');\n })\n .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nexport const indicatorOptionsSchema: Joi.ObjectSchema<Indicator> = Joi.object({\n resource: resourceValidationSchema,\n scopes: scopesValidationSchema.optional(),\n});\n\nexport const optionsSchema: Joi.ObjectSchema<MonoCloudOptionsBase> = Joi.object(\n {\n clientId: stringRequired,\n clientSecret: stringRequired,\n tenantDomain: stringRequired.uri(),\n cookieSecret: stringRequired.min(8),\n appUrl: stringRequired.uri(),\n routes: routesSchema,\n clockSkew: numRequired,\n responseTimeout: numRequired.min(1000),\n usePar: boolRequired,\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n federatedSignOut: boolRequired,\n fetchUserInfo: boolRequired,\n refetchUserInfo: boolRequired,\n allowQueryParamOverrides: boolRequired,\n strictProfileSync: boolRequired,\n defaultAuthParams: authParamSchema,\n resources: Joi.array<Indicator>().items(indicatorOptionsSchema).optional(),\n session: sessionSchema,\n state: stateSchema,\n idTokenSigningAlg: Joi.string().valid(\n 'RS256',\n 'RS384',\n 'RS512',\n 'PS256',\n 'PS384',\n 'PS512',\n 'ES256',\n 'ES384',\n 'ES512'\n ),\n filteredIdTokenClaims: Joi.array<string>().items(stringRequired),\n debugger: stringRequired,\n userAgent: stringRequired,\n jwksCacheDuration: numOptional,\n metadataCacheDuration: numOptional,\n onBackChannelLogout: funcOptional,\n onSetApplicationState: funcOptional,\n onSessionCreating: funcOptional,\n }\n);\n\nexport const signInOptionsSchema: Joi.ObjectSchema<SignInOptions> = Joi.object({\n returnUrl: stringOptional.uri({ allowRelative: true }),\n register: boolOptional,\n authParams: optionalAuthParamSchema,\n onError: funcOptional,\n});\n\nexport const callbackOptionsSchema: Joi.ObjectSchema<CallbackOptions> =\n Joi.object({\n fetchUserInfo: boolOptional,\n redirectUri: stringOptional.uri(),\n onError: funcOptional,\n });\n\nexport const userInfoOptionsSchema: Joi.ObjectSchema<UserInfoOptions> =\n Joi.object({\n refresh: boolOptional,\n onError: funcOptional,\n });\n\nexport const signOutOptionsSchema: Joi.ObjectSchema<SignOutOptions> =\n Joi.object({\n postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n idToken: stringOptional,\n state: stringOptional,\n federatedSignOut: boolOptional,\n onError: funcOptional,\n });\n\nexport const getTokensOptionsSchema: Joi.ObjectSchema<GetTokensOptions> =\n Joi.object({\n forceRefresh: boolOptional,\n refetchUserInfo: boolOptional,\n resource: resourceValidationSchema.optional(),\n scopes: scopesValidationSchema.optional(),\n });\n\nexport const getSessionOptionsSchema: Joi.ObjectSchema<GetSessionOptions> =\n Joi.object({\n refetchUserInfo: boolOptional,\n });\n","/* eslint-disable prefer-destructuring */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {\n getBoolean,\n getNumber,\n removeTrailingSlash,\n} from '@monocloud/auth-core/internal';\nimport {\n MonoCloudOptions,\n MonoCloudOptionsBase,\n SameSiteValues,\n} from '../types';\nimport { DEFAULT_OPTIONS } from './defaults';\nimport { optionsSchema } from './validation';\nimport {\n MonoCloudValidationError,\n SecurityAlgorithms,\n} from '@monocloud/auth-core';\n\nexport const getOptions = (\n options?: MonoCloudOptions,\n throwOnError = true\n): MonoCloudOptionsBase => {\n const MONOCLOUD_AUTH_CLIENT_ID = process.env.MONOCLOUD_AUTH_CLIENT_ID;\n const MONOCLOUD_AUTH_CLIENT_SECRET = process.env.MONOCLOUD_AUTH_CLIENT_SECRET;\n const MONOCLOUD_AUTH_TENANT_DOMAIN = process.env.MONOCLOUD_AUTH_TENANT_DOMAIN;\n const MONOCLOUD_AUTH_SCOPES = process.env.MONOCLOUD_AUTH_SCOPES;\n const MONOCLOUD_AUTH_COOKIE_SECRET = process.env.MONOCLOUD_AUTH_COOKIE_SECRET;\n const MONOCLOUD_AUTH_APP_URL = process.env.MONOCLOUD_AUTH_APP_URL;\n const MONOCLOUD_AUTH_CALLBACK_URL = process.env.MONOCLOUD_AUTH_CALLBACK_URL;\n const MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL =\n process.env.MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL;\n const MONOCLOUD_AUTH_SIGNIN_URL = process.env.MONOCLOUD_AUTH_SIGNIN_URL;\n const MONOCLOUD_AUTH_SIGNOUT_URL = process.env.MONOCLOUD_AUTH_SIGNOUT_URL;\n const MONOCLOUD_AUTH_USER_INFO_URL = process.env.MONOCLOUD_AUTH_USER_INFO_URL;\n const MONOCLOUD_AUTH_RESOURCE = process.env.MONOCLOUD_AUTH_RESOURCE;\n const MONOCLOUD_AUTH_CLOCK_SKEW = process.env.MONOCLOUD_AUTH_CLOCK_SKEW;\n const MONOCLOUD_AUTH_RESPONSE_TIMEOUT =\n process.env.MONOCLOUD_AUTH_RESPONSE_TIMEOUT;\n const MONOCLOUD_AUTH_USE_PAR = process.env.MONOCLOUD_AUTH_USE_PAR;\n const MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI =\n process.env.MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI;\n const MONOCLOUD_AUTH_FEDERATED_SIGNOUT =\n process.env.MONOCLOUD_AUTH_FEDERATED_SIGNOUT;\n const MONOCLOUD_AUTH_FETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;\n const MONOCLOUD_AUTH_REFETCH_USER_INFO =\n process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;\n const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES =\n process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;\n const MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC =\n process.env.MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC;\n const MONOCLOUD_AUTH_SESSION_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;\n const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SECURE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_SESSION_SLIDING =\n process.env.MONOCLOUD_AUTH_SESSION_SLIDING;\n const MONOCLOUD_AUTH_SESSION_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_DURATION;\n const MONOCLOUD_AUTH_SESSION_MAX_DURATION =\n process.env.MONOCLOUD_AUTH_SESSION_MAX_DURATION;\n const MONOCLOUD_AUTH_STATE_COOKIE_NAME =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_NAME;\n const MONOCLOUD_AUTH_STATE_COOKIE_PATH =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PATH;\n const MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN;\n const MONOCLOUD_AUTH_STATE_COOKIE_SECURE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SECURE;\n const MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE;\n const MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT =\n process.env.MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT;\n const MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG =\n process.env.MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG;\n const MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS =\n process.env.MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS;\n const MONOCLOUD_AUTH_JWKS_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_JWKS_CACHE_DURATION;\n const MONOCLOUD_AUTH_METADATA_CACHE_DURATION =\n process.env.MONOCLOUD_AUTH_METADATA_CACHE_DURATION;\n\n const appUrl = options?.appUrl ?? MONOCLOUD_AUTH_APP_URL!;\n\n const opt: MonoCloudOptionsBase = {\n clientId: options?.clientId ?? MONOCLOUD_AUTH_CLIENT_ID!,\n clientSecret: options?.clientSecret ?? MONOCLOUD_AUTH_CLIENT_SECRET,\n tenantDomain: options?.tenantDomain ?? MONOCLOUD_AUTH_TENANT_DOMAIN!,\n defaultAuthParams: {\n ...(options?.defaultAuthParams ?? {}),\n scopes:\n options?.defaultAuthParams?.scopes ??\n MONOCLOUD_AUTH_SCOPES ??\n DEFAULT_OPTIONS.defaultAuthParams.scopes,\n responseType:\n options?.defaultAuthParams?.responseType ??\n (DEFAULT_OPTIONS.defaultAuthParams.responseType as any),\n resource: options?.defaultAuthParams?.resource ?? MONOCLOUD_AUTH_RESOURCE,\n },\n resources: options?.resources,\n cookieSecret: options?.cookieSecret ?? MONOCLOUD_AUTH_COOKIE_SECRET!,\n appUrl: removeTrailingSlash(appUrl),\n routes: {\n callback: removeTrailingSlash(\n options?.routes?.callback ??\n MONOCLOUD_AUTH_CALLBACK_URL ??\n DEFAULT_OPTIONS.routes.callback\n ),\n backChannelLogout: removeTrailingSlash(\n options?.routes?.backChannelLogout ??\n MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL ??\n DEFAULT_OPTIONS.routes.backChannelLogout\n ),\n signIn: removeTrailingSlash(\n options?.routes?.signIn ??\n MONOCLOUD_AUTH_SIGNIN_URL ??\n DEFAULT_OPTIONS.routes.signIn\n ),\n signOut: removeTrailingSlash(\n options?.routes?.signOut ??\n MONOCLOUD_AUTH_SIGNOUT_URL ??\n DEFAULT_OPTIONS.routes.signOut\n ),\n userInfo: removeTrailingSlash(\n options?.routes?.userInfo ??\n MONOCLOUD_AUTH_USER_INFO_URL ??\n DEFAULT_OPTIONS.routes.userInfo\n ),\n },\n clockSkew:\n options?.clockSkew ??\n getNumber(MONOCLOUD_AUTH_CLOCK_SKEW) ??\n DEFAULT_OPTIONS.clockSkew,\n responseTimeout:\n options?.responseTimeout ??\n getNumber(MONOCLOUD_AUTH_RESPONSE_TIMEOUT) ??\n DEFAULT_OPTIONS.responseTimeout,\n usePar:\n options?.usePar ??\n getBoolean(MONOCLOUD_AUTH_USE_PAR) ??\n DEFAULT_OPTIONS.usePar,\n postLogoutRedirectUri:\n options?.postLogoutRedirectUri ?? MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI,\n federatedSignOut:\n options?.federatedSignOut ??\n getBoolean(MONOCLOUD_AUTH_FEDERATED_SIGNOUT) ??\n DEFAULT_OPTIONS.federatedSignOut,\n fetchUserInfo:\n options?.fetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_FETCH_USER_INFO) ??\n DEFAULT_OPTIONS.fetchUserInfo,\n refetchUserInfo:\n options?.refetchUserInfo ??\n getBoolean(MONOCLOUD_AUTH_REFETCH_USER_INFO) ??\n DEFAULT_OPTIONS.refetchUserInfo,\n allowQueryParamOverrides:\n options?.allowQueryParamOverrides ??\n getBoolean(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ??\n DEFAULT_OPTIONS.allowQueryParamOverrides,\n strictProfileSync:\n options?.strictProfileSync ??\n getBoolean(MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC) ??\n DEFAULT_OPTIONS.strictProfileSync,\n session: {\n cookie: {\n name:\n options?.session?.cookie?.name ??\n MONOCLOUD_AUTH_SESSION_COOKIE_NAME ??\n DEFAULT_OPTIONS.session.cookie.name,\n path:\n options?.session?.cookie?.path ??\n MONOCLOUD_AUTH_SESSION_COOKIE_PATH ??\n DEFAULT_OPTIONS.session.cookie.path,\n domain:\n options?.session?.cookie?.domain ??\n MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN,\n httpOnly:\n options?.session?.cookie?.httpOnly ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY) ??\n DEFAULT_OPTIONS.session.cookie.httpOnly,\n secure:\n options?.session?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.session?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.session.cookie.sameSite,\n persistent:\n options?.session?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.session.cookie.persistent,\n },\n sliding:\n options?.session?.sliding ??\n getBoolean(MONOCLOUD_AUTH_SESSION_SLIDING) ??\n DEFAULT_OPTIONS.session.sliding,\n duration:\n options?.session?.duration ??\n getNumber(MONOCLOUD_AUTH_SESSION_DURATION) ??\n DEFAULT_OPTIONS.session.duration,\n maximumDuration:\n options?.session?.maximumDuration ??\n getNumber(MONOCLOUD_AUTH_SESSION_MAX_DURATION) ??\n DEFAULT_OPTIONS.session.maximumDuration,\n store: options?.session?.store,\n },\n state: {\n cookie: {\n name:\n options?.state?.cookie?.name ??\n MONOCLOUD_AUTH_STATE_COOKIE_NAME ??\n DEFAULT_OPTIONS.state.cookie.name,\n path:\n options?.state?.cookie?.path ??\n MONOCLOUD_AUTH_STATE_COOKIE_PATH ??\n DEFAULT_OPTIONS.state.cookie.path,\n domain:\n options?.state?.cookie?.domain ?? MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN,\n httpOnly: DEFAULT_OPTIONS.state.cookie.httpOnly,\n secure:\n options?.state?.cookie?.secure ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_SECURE) ??\n appUrl?.startsWith('https:'),\n sameSite:\n options?.state?.cookie?.sameSite ??\n (MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE as SameSiteValues) ??\n DEFAULT_OPTIONS.state.cookie.sameSite,\n persistent:\n options?.state?.cookie?.persistent ??\n getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT) ??\n DEFAULT_OPTIONS.state.cookie.persistent,\n },\n },\n idTokenSigningAlg:\n options?.idTokenSigningAlg ??\n (MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG as SecurityAlgorithms) ??\n DEFAULT_OPTIONS.idTokenSigningAlg,\n filteredIdTokenClaims:\n options?.filteredIdTokenClaims ??\n MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS?.split(' ')\n .map(x => x.trim())\n .filter(x => x.length) ??\n DEFAULT_OPTIONS.filteredIdTokenClaims,\n debugger: options?.debugger ?? DEFAULT_OPTIONS.debugger,\n userAgent: options?.userAgent ?? DEFAULT_OPTIONS.userAgent,\n jwksCacheDuration:\n options?.jwksCacheDuration ??\n getNumber(MONOCLOUD_AUTH_JWKS_CACHE_DURATION),\n metadataCacheDuration:\n options?.metadataCacheDuration ??\n getNumber(MONOCLOUD_AUTH_METADATA_CACHE_DURATION),\n onBackChannelLogout: options?.onBackChannelLogout,\n onSetApplicationState: options?.onSetApplicationState,\n onSessionCreating: options?.onSessionCreating,\n };\n\n const { value, error } = optionsSchema.validate(opt, { abortEarly: false });\n\n const requiredEnv: Record<string, string> = {\n tenantDomain: 'MONOCLOUD_AUTH_TENANT_DOMAIN',\n clientId: 'MONOCLOUD_AUTH_CLIENT_ID',\n clientSecret: 'MONOCLOUD_AUTH_CLIENT_SECRET',\n appUrl: 'MONOCLOUD_AUTH_APP_URL',\n cookieSecret: 'MONOCLOUD_AUTH_COOKIE_SECRET',\n };\n\n if (error) {\n if (throwOnError) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n 'WARNING: One or more configuration options were not provided for MonoCloudClient.'\n );\n error.details.forEach(detail => {\n if (detail.context?.key && requiredEnv[detail.context.key]) {\n // eslint-disable-next-line no-console\n console.warn(\n `Missing: ${detail.context.key} - Set ${requiredEnv[detail.context.key]} environment variable in your .env file.`\n );\n }\n });\n }\n\n return value;\n};\n","import { createRemoteJWKSet, JWTPayload, jwtVerify } from 'jose';\nimport {\n ensureLeadingSlash,\n findToken,\n getBoolean,\n isAbsoluteUrl,\n isPresent,\n isSameHost,\n now,\n parseSpaceSeparated,\n parseSpaceSeparatedSet,\n setsEqual,\n} from '@monocloud/auth-core/internal';\nimport {\n generateNonce,\n generatePKCE,\n generateState,\n isUserInGroup,\n mergeArrays,\n parseCallbackParams,\n} from '@monocloud/auth-core/utils';\nimport type {\n Authenticators,\n AuthorizationParams,\n DisplayOptions,\n IssuerMetadata,\n MonoCloudSession,\n Prompt,\n} from '@monocloud/auth-core';\nimport {\n MonoCloudOidcClient,\n MonoCloudOPError,\n MonoCloudTokenError,\n MonoCloudValidationError,\n} from '@monocloud/auth-core';\nimport { MonoCloudSessionService } from './monocloud-session-service';\nimport { MonoCloudStateService } from './monocloud-state-service';\nimport { getOptions } from './options/get-options';\nimport {\n ApplicationState,\n CallbackOptions,\n GetSessionOptions,\n GetTokensOptions,\n MonoCloudOptions,\n MonoCloudOptionsBase,\n MonoCloudState,\n MonoCloudTokens,\n SignInOptions,\n SignOutOptions,\n UserInfoOptions,\n} from './types';\nimport {\n IMonoCloudCookieRequest,\n IMonoCloudCookieResponse,\n MonoCloudRequest,\n MonoCloudResponse,\n} from './types/internal';\nimport {\n callbackOptionsSchema,\n getSessionOptionsSchema,\n getTokensOptionsSchema,\n resourceValidationSchema,\n scopesValidationSchema,\n signInOptionsSchema,\n signOutOptionsSchema,\n userInfoOptionsSchema,\n} from './options/validation';\nimport dbug, { Debugger } from 'debug';\n\n/**\n * @category Classes\n */\nexport class MonoCloudCoreClient {\n public readonly oidcClient: MonoCloudOidcClient;\n\n private readonly options: MonoCloudOptionsBase;\n\n private readonly stateService: MonoCloudStateService;\n\n private readonly sessionService: MonoCloudSessionService;\n\n private readonly debug: Debugger;\n\n private optionsValidated = false;\n\n constructor(partialOptions?: MonoCloudOptions) {\n this.options = getOptions(partialOptions, false);\n this.oidcClient = new MonoCloudOidcClient(\n this.options.tenantDomain,\n this.options.clientId,\n {\n clientSecret: this.options.clientSecret,\n idTokenSigningAlgorithm: this.options.idTokenSigningAlg,\n }\n );\n this.debug = dbug(this.options.debugger);\n this.stateService = new MonoCloudStateService(this.options);\n this.sessionService = new MonoCloudSessionService(this.options);\n\n /* v8 ignore next -- @preserve */\n if (process.env.DEBUG && !this.debug.enabled) {\n dbug.enable(process.env.DEBUG);\n }\n\n this.debug('Debug logging enabled.');\n }\n\n /**\n * Initiates the sign-in flow by redirecting the user to the MonoCloud authorization endpoint.\n *\n * This method handles scope and resource merging, state generation (nonce, state, PKCE),\n * and constructing the final authorization URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signInOptions - Configuration to customize the sign-in behavior.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} When validation of parameters or state fails.\n */\n async signIn(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signInOptions?: SignInOptions\n ): Promise<any> {\n this.debug('Starting sign-in handler');\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const indicatorResource = this.options.resources\n ?.map(x => x.resource)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n const indicatorScopes = this.options.resources\n ?.map(x => x.scopes)\n .filter(x => !!x)\n .reduce((acc, x) => `${acc} ${x}`, '');\n\n const mergedScopes = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.scopes),\n parseSpaceSeparated(this.options.defaultAuthParams.scopes),\n parseSpaceSeparated(indicatorScopes)\n ) ?? ['openid'];\n\n const mergedResources = mergeArrays(\n parseSpaceSeparated(signInOptions?.authParams?.resource),\n parseSpaceSeparated(this.options.defaultAuthParams.resource),\n parseSpaceSeparated(indicatorResource)\n );\n\n // Merge the sign-in options and the default options\n const opt = {\n ...(signInOptions ?? {}),\n authParams: {\n ...this.options.defaultAuthParams,\n ...signInOptions?.authParams,\n scopes: mergedScopes.join(' '),\n acrValues: mergeArrays(\n signInOptions?.authParams?.acrValues,\n this.options.defaultAuthParams.acrValues\n ),\n resource: mergedResources?.join(' '),\n },\n };\n\n let appState: ApplicationState = {};\n\n // Set the application state if the onSetApplicationState function is set\n if (this.options.onSetApplicationState) {\n appState = await this.options.onSetApplicationState(request);\n\n // Validate the custom sign-in state\n if (\n appState === null ||\n appState === undefined ||\n typeof appState !== 'object' ||\n Array.isArray(appState)\n ) {\n throw new MonoCloudValidationError(\n 'Invalid Application State. Expected state to be an object'\n );\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n returnUrl: request.getQuery('return_url') as string,\n authenticatorHint: request.getQuery(\n 'authenticator_hint'\n ) as Authenticators,\n scope: request.getQuery('scope') as string,\n resource: request.getQuery('resource') as string,\n display: request.getQuery('display') as DisplayOptions,\n uiLocales: request.getQuery('ui_locales') as string,\n acrValues: request.getQuery('acr_values') as string,\n loginHint: request.getQuery('login_hint') as string,\n prompt: request.getQuery('prompt') as Prompt,\n maxAge: parseInt(request.getQuery('max_age') as string, 10),\n }\n : {};\n\n // Set the return url if passed down\n const retUrl = query.returnUrl ?? opt.returnUrl;\n if (\n typeof retUrl === 'string' &&\n retUrl &&\n (!isAbsoluteUrl(retUrl) || isSameHost(this.options.appUrl, retUrl))\n ) {\n opt.returnUrl = retUrl;\n }\n\n // Validate the options\n const { error } = signInOptionsSchema.validate(opt, { abortEarly: true });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n\n // Generate the state, nonce & code verifier\n const state = generateState();\n const nonce = generateNonce();\n const { codeChallenge, codeVerifier } = await generatePKCE();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (!isNaN(query.maxAge!)) {\n opt.authParams.maxAge = query.maxAge;\n }\n\n // Ensure that return to is present, if not then use the base url as the return to\n const returnUrl = encodeURIComponent(\n opt.returnUrl ?? this.options.appUrl\n );\n\n const redirectUrl = `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n // Create the Authorization Parameters\n let params: AuthorizationParams = {\n redirectUri: redirectUrl,\n ...opt.authParams,\n nonce,\n state,\n codeChallenge,\n };\n\n // Set the Authenticator if passed down\n const authenticatorHint =\n query.authenticatorHint ?? opt.authParams.authenticatorHint;\n if (typeof authenticatorHint === 'string' && authenticatorHint) {\n params.authenticatorHint = authenticatorHint;\n }\n\n const scopes =\n (typeof query.scope === 'string' ? query.scope : undefined) ??\n opt.authParams.scopes;\n\n if (scopes) {\n const { error: e } = scopesValidationSchema.validate(scopes, {\n abortEarly: true,\n });\n\n if (!e) {\n params.scopes = scopes;\n }\n }\n\n const resource =\n (typeof query.resource === 'string' ? query.resource : undefined) ??\n opt.authParams.resource;\n\n // Set the resources mode if passed down\n if (resource) {\n const { error: e } = resourceValidationSchema.validate(resource, {\n abortEarly: true,\n });\n\n if (!e) {\n params.resource = resource;\n }\n }\n\n // Set the display if passed down\n const display = query.display ?? opt.authParams.display;\n if (typeof display === 'string' && display) {\n params.display = display as unknown as DisplayOptions;\n }\n\n // Set the ui locales if passed down\n const uiLocales = query.uiLocales ?? opt.authParams.uiLocales;\n if (typeof uiLocales === 'string' && uiLocales) {\n params.uiLocales = uiLocales;\n }\n\n // Set the acr values if passed down\n const acrValues = query.acrValues ?? opt.authParams.acrValues;\n if (typeof acrValues === 'string' && acrValues) {\n params.acrValues = acrValues\n .split(' ')\n .map(x => x.trim())\n .filter(x => x !== '');\n }\n\n // Set the login hint if passed down\n const loginHint = query.loginHint ?? opt.authParams.loginHint;\n if (typeof loginHint === 'string' && loginHint) {\n params.loginHint = loginHint;\n }\n\n // Set the prompt if passed down\n let prompt: string | undefined;\n if (typeof query.prompt === 'string') {\n prompt = query.prompt;\n } else {\n prompt = opt.register ? 'create' : opt.authParams.prompt;\n }\n\n if (prompt) {\n params.prompt = prompt as Prompt;\n }\n\n /* v8 ignore next -- @preserve */\n if (!params.scopes || params.scopes.length < 0) {\n throw new MonoCloudValidationError(\n 'Scopes are required for signing in'\n );\n }\n\n // Generate the monocloud state\n const monoCloudState: MonoCloudState = {\n returnUrl,\n state,\n nonce,\n codeVerifier,\n maxAge: opt.authParams.maxAge,\n appState: JSON.stringify(appState),\n resource: this.options.defaultAuthParams.resource,\n scopes: params.scopes,\n };\n\n if (this.options.usePar) {\n const { request_uri } =\n await this.oidcClient.pushedAuthorizationRequest(params);\n\n params = {\n requestUri: request_uri,\n };\n }\n\n // Create authorize url\n const authUrl = await this.oidcClient.authorizationUrl(params);\n\n // Set the state cookie\n await this.stateService.setState(\n response,\n monoCloudState,\n params.responseMode === 'form_post' ? 'none' : undefined\n );\n // Redirect to authorize url\n response.redirect(authUrl, 302);\n } catch (error) {\n if (typeof signInOptions?.onError === 'function') {\n return signInOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles the OpenID callback after the user authenticates with MonoCloud.\n *\n * Processes the authorization code, validates the state and nonce, exchanges the code for tokens,\n * initializes the user session, and performs the final redirect to the application's return URL.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param callbackOptions - Optional configuration for the callback handler.\n * @returns A promise that resolves when the callback processing and redirection are complete.\n *\n * @throws {@link MonoCloudValidationError} If the state is mismatched or tokens are invalid.\n */\n async callback(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n callbackOptions?: CallbackOptions\n ): Promise<any> {\n this.debug('Starting callback handler');\n\n try {\n this.validateOptions();\n\n const { method, url, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get' && method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the callback Options\n if (callbackOptions) {\n const { error } = callbackOptionsSchema.validate(callbackOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the state value\n const monoCloudState = await this.stateService.getState(\n request,\n response\n );\n\n // Handle invalid state\n if (!monoCloudState) {\n throw new MonoCloudValidationError('Invalid Authentication State');\n }\n\n let fullUrl = url;\n\n // check if the url is a relative url\n if (!isAbsoluteUrl(url)) {\n fullUrl = `${this.options.appUrl}${ensureLeadingSlash(url)}`;\n }\n\n // Get the search parameters or the body\n const payload =\n method.toLowerCase() === 'post'\n ? new URLSearchParams(body)\n : new URL(fullUrl).searchParams;\n\n // Get the parameters returned from the server\n const callbackParams = parseCallbackParams(payload);\n\n if (callbackParams.state !== monoCloudState.state) {\n throw new MonoCloudValidationError('Invalid state');\n }\n\n if (isPresent(callbackParams.error)) {\n throw new MonoCloudOPError(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n callbackParams.error!,\n callbackParams.errorDescription\n );\n }\n\n // Get the redirect Url to be validated\n const redirectUri =\n callbackOptions?.redirectUri ??\n `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n if (!callbackParams.code) {\n throw new MonoCloudValidationError(\n 'Authorization code not found in callback params'\n );\n }\n\n // Parse the client state\n const appState: ApplicationState = JSON.parse(monoCloudState.appState);\n\n const session = await this.oidcClient.authenticate(\n callbackParams.code,\n redirectUri,\n monoCloudState.scopes,\n monoCloudState.resource,\n {\n codeVerifier: monoCloudState.codeVerifier,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenNonce: monoCloudState.nonce,\n idTokenMaxAge: monoCloudState.maxAge,\n idTokenClockTolerance: 5,\n fetchUserInfo:\n callbackOptions?.fetchUserInfo ?? this.options.fetchUserInfo,\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: async (s, i, u) =>\n await this.options.onSessionCreating?.(s, i, u, appState),\n }\n );\n\n // Set the user session\n await this.sessionService.setSession(request, response, session);\n\n // Return to base url if no return url was set\n if (!monoCloudState.returnUrl) {\n response.redirect(this.options.appUrl);\n return response.done();\n }\n\n // Return to a valid return to url\n try {\n const decodedUrl = decodeURIComponent(monoCloudState.returnUrl);\n\n if (!isAbsoluteUrl(decodedUrl)) {\n response.redirect(\n `${this.options.appUrl}${ensureLeadingSlash(decodedUrl)}`\n );\n return response.done();\n }\n\n if (isSameHost(this.options.appUrl, decodedUrl)) {\n response.redirect(decodedUrl);\n return response.done();\n }\n } catch {\n // do nothing\n }\n\n response.redirect(this.options.appUrl);\n } catch (error) {\n if (typeof callbackOptions?.onError === 'function') {\n return callbackOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Retrieves user information, optionally refetching fresh data from the UserInfo endpoint.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param userinfoOptions - Configuration to control refetching and error handling.\n * @returns A promise that resolves with the user information sent as a JSON response.\n *\n * @remarks\n * If `refresh` is true, the session is updated with fresh claims from the identity provider.\n */\n async userInfo(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n userinfoOptions?: UserInfoOptions\n ): Promise<any> {\n this.debug('Starting userinfo handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the User Info options\n if (userinfoOptions) {\n const { error } = userInfoOptionsSchema.validate(userinfoOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? { refresh: getBoolean(request.getQuery('refresh') as string) }\n : {};\n\n const refetchUserInfo =\n query.refresh ??\n userinfoOptions?.refresh ??\n this.options.refetchUserInfo;\n\n // Get the user session\n const session = await this.sessionService.getSession(\n request,\n response,\n !refetchUserInfo\n );\n\n // Handle no session\n if (!session) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n const defaultToken = findToken(\n session.accessTokens,\n this.options.defaultAuthParams.resource,\n session.authorizedScopes\n );\n\n // If refetch is false then return the session\n if (!refetchUserInfo || !defaultToken) {\n response.sendJson(session.user);\n return response.done();\n }\n\n // Get the new session\n const newSession = await this.oidcClient.refetchUserInfo(\n defaultToken,\n session,\n {\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n strictProfileSync: this.options.strictProfileSync,\n }\n );\n\n // Update the session containing the new claims\n const updated = await this.sessionService.updateSession(\n request,\n response,\n newSession\n );\n\n // Handle session was not updated successfully\n if (!updated) {\n response.setNoCache();\n response.noContent();\n return response.done();\n }\n\n // Return the Claims\n response.sendJson(session.user);\n } catch (error) {\n if (typeof userinfoOptions?.onError === 'function') {\n return userinfoOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Initiates the sign-out flow, destroying the local session and optionally performing federated sign-out.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n * @param signOutOptions - Configuration for post-logout behavior and federated sign-out.\n *\n * @returns A promise that resolves when the sign-out redirection is initiated.\n */\n async signOut(\n request: MonoCloudRequest,\n response: MonoCloudResponse,\n signOutOptions?: SignOutOptions\n ): Promise<any> {\n this.debug('Starting sign-out handler');\n\n try {\n this.validateOptions();\n\n const { method } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'get') {\n response.methodNotAllowed();\n return response.done();\n }\n\n // Validate the sign-out options\n if (signOutOptions) {\n const { error } = signOutOptionsSchema.validate(signOutOptions, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const query = this.options.allowQueryParamOverrides\n ? {\n postLogoutUrl: request.getQuery('post_logout_url') as string,\n federated: getBoolean(request.getQuery('federated') as string),\n }\n : {};\n\n // Build the return to url\n let returnUrl =\n this.options.postLogoutRedirectUri ??\n signOutOptions?.postLogoutRedirectUri ??\n this.options.appUrl;\n\n // Set the return url if passed down\n if (query.postLogoutUrl) {\n const { error } = signOutOptionsSchema.validate({\n postLogoutRedirectUri: query.postLogoutUrl,\n });\n\n if (!error) {\n returnUrl = query.postLogoutUrl;\n }\n }\n\n // Ensure the return to is an absolute one\n if (!isAbsoluteUrl(returnUrl)) {\n returnUrl = `${this.options.appUrl}${ensureLeadingSlash(returnUrl)}`;\n }\n\n // Get the current session\n const session = await this.sessionService.getSession(\n request,\n response,\n false\n );\n\n // Redirect to return url if session doesn't exist\n if (!session) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n await this.sessionService.removeSession(request, response);\n\n // Handle Federated Sign Out\n const isFederatedSignOut =\n query.federated ??\n signOutOptions?.federatedSignOut ??\n this.options.federatedSignOut;\n\n if (!isFederatedSignOut) {\n response.redirect(returnUrl);\n return response.done();\n }\n\n // Build the end session Url\n const url = await this.oidcClient.endSessionUrl({\n idToken: session.idToken,\n postLogoutRedirectUri: returnUrl,\n state: signOutOptions?.state,\n });\n\n // Redirect the user to the end session endpoint\n response.redirect(url);\n } catch (error) {\n if (typeof signOutOptions?.onError === 'function') {\n return signOutOptions.onError(error as Error);\n } else {\n this.handleCatchAll(error as Error, response);\n }\n }\n\n return response.done();\n }\n\n /**\n * Handles Back-Channel Logout notifications from the identity provider.\n *\n * Validates the Logout Token and triggers the `onBackChannelLogout` callback defined in options.\n *\n * @param request - MonoCloud request object.\n * @param response - MonoCloud response object.\n *\n * @returns A promise that resolves when the logout notification has been processed.\n *\n * @throws {@link MonoCloudValidationError} If the logout token is missing or invalid.\n */\n async backChannelLogout(\n request: MonoCloudRequest,\n response: MonoCloudResponse\n ): Promise<any> {\n this.debug('Starting back-channel logout handler');\n\n try {\n this.validateOptions();\n\n response.setNoCache();\n\n if (!this.options.onBackChannelLogout) {\n response.notFound();\n return response.done();\n }\n\n const { method, body } = await request.getRawRequest();\n\n if (method.toLowerCase() !== 'post') {\n response.methodNotAllowed();\n return response.done();\n }\n\n const params = new URLSearchParams(body);\n const logoutToken = params.get('logout_token');\n\n if (!logoutToken) {\n throw new MonoCloudValidationError('Missing Logout Token');\n }\n\n const metadata = await this.oidcClient.getMetadata();\n\n const { sid, sub } = await this.verifyLogoutToken(logoutToken, metadata);\n\n await this.options.onBackChannelLogout(sub, sid as any);\n\n response.noContent();\n } catch (error) {\n this.handleCatchAll(error as Error, response);\n }\n\n return response.done();\n }\n\n /**\n * Checks if the current request has an active and authenticated session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @returns `true` if a valid session with user data exists, `false` otherwise.\n *\n */\n async isAuthenticated(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<boolean> {\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n // Return true if the session exists\n return !!session?.user;\n }\n\n /**\n * Checks if the current session user belongs to the specified groups.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param groups - List of group names or IDs to check.\n * @param groupsClaim - Optional claim name that holds groups. Defaults to \"groups\".\n * @param matchAll - If `true`, requires membership in all groups; otherwise any one group is sufficient.\n *\n * @returns `true` if the user satisfies the group condition, `false` otherwise.\n */\n async isUserInGroup(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n groups: string[],\n groupsClaim?: string,\n matchAll?: boolean\n ): Promise<boolean> {\n const session = await this.sessionService.getSession(request, response);\n\n if (!session?.user) {\n return false;\n }\n\n return isUserInGroup(session.user, groups, groupsClaim, matchAll);\n }\n\n /**\n * Retrieves the current user's session data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param options - Optional configuration to control session retrieval behavior.\n *\n * @returns Session or `undefined`.\n */\n async getSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n options?: GetSessionOptions\n ): Promise<MonoCloudSession | undefined> {\n if (options) {\n const { error } = getSessionOptionsSchema.validate(options, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n const session = await this.sessionService.getSession(request, response);\n\n if (!options?.refetchUserInfo || !session) {\n return session;\n }\n\n const defaultToken = findToken(\n session.accessTokens,\n this.options.defaultAuthParams.resource,\n session.authorizedScopes\n );\n\n if (!defaultToken) {\n throw new MonoCloudValidationError('Access token not found');\n }\n\n const newSession = await this.oidcClient.refetchUserInfo(\n defaultToken,\n session,\n {\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n strictProfileSync: this.options.strictProfileSync,\n }\n );\n\n await this.sessionService.updateSession(request, response, newSession);\n\n return newSession;\n }\n\n /**\n * Updates the current user's session with new data.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param session - The updated session object to persist.\n */\n async updateSession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n session: MonoCloudSession\n ): Promise<void> {\n await this.sessionService.updateSession(request, response, session);\n }\n\n /**\n * Returns a copy of the current client configuration options.\n *\n * @returns A copy of the initialized configuration.\n */\n getOptions(): MonoCloudOptionsBase {\n return { ...this.options };\n }\n\n /**\n * Destroys the local user session.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n *\n * @remarks\n * This does not perform federated sign-out. For identity provider sign-out, use `signOut` handler.\n */\n destroySession(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse\n ): Promise<void> {\n return this.sessionService.removeSession(request, response);\n }\n\n /**\n * Retrieves active tokens (Access, ID, Refresh), performing a refresh if they are expired or missing.\n *\n * @param request - MonoCloud cookie request object.\n * @param response - MonoCloud cookie response object.\n * @param options - Configuration for token retrieval (force refresh, specific scopes/resources).\n *\n * @returns Fetched tokens.\n *\n * @throws {@link MonoCloudValidationError} If the session does not exist or tokens cannot be found/refreshed.\n */\n async getTokens(\n request: IMonoCloudCookieRequest,\n response: IMonoCloudCookieResponse,\n options?: GetTokensOptions\n ): Promise<MonoCloudTokens> {\n // Validate the get tokens options\n if (options) {\n const { error } = getTokensOptionsSchema.validate(options, {\n abortEarly: true,\n });\n\n if (error) {\n throw new MonoCloudValidationError(error.details[0].message);\n }\n }\n\n // Get the session\n const session = await this.sessionService.getSession(request, response);\n\n if (!session) {\n throw new MonoCloudValidationError('Session does not exist');\n }\n\n let scopes = options?.scopes;\n\n const resource =\n options?.resource ?? this.options.defaultAuthParams.resource;\n\n if (isPresent(options?.resource)) {\n if (!isPresent(scopes)) {\n // Check if there is a resource with undefined scope\n const noScopeResource = this.options.resources?.find(\n x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n ) && !x.scopes\n );\n\n // Search for the same resource with scopes defined\n if (!noScopeResource) {\n scopes = this.options.resources?.find(x =>\n setsEqual(\n parseSpaceSeparatedSet(x.resource),\n parseSpaceSeparatedSet(resource)\n )\n )?.scopes;\n }\n }\n }\n\n const findTokenScopes =\n !isPresent(options?.resource) && !isPresent(scopes)\n ? session.authorizedScopes\n : scopes;\n\n let token = findToken(session.accessTokens, resource, findTokenScopes);\n\n const tokenExpired = !!token && token.accessTokenExpiration - 30 < now();\n\n let { idToken } = session;\n let { refreshToken } = session;\n\n if (options?.forceRefresh || !token || tokenExpired) {\n if (!refreshToken && token && tokenExpired) {\n throw new MonoCloudTokenError(\n 'No refresh token available to refresh the expired access token'\n );\n }\n\n const updatedSession = await this.oidcClient.refreshSession(session, {\n fetchUserInfo: options?.refetchUserInfo ?? this.options.refetchUserInfo,\n validateIdToken: true,\n idTokenClockSkew: this.options.clockSkew,\n idTokenClockTolerance: 5,\n refreshGrantOptions: {\n resource,\n scopes,\n },\n filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n onSessionCreating: this.options.onSessionCreating?.bind(this),\n strictProfileSync: this.options.strictProfileSync,\n });\n\n await this.sessionService.updateSession(\n request,\n response,\n updatedSession\n );\n\n token = findToken(\n updatedSession?.accessTokens,\n resource,\n findTokenScopes\n );\n\n idToken = updatedSession.idToken;\n refreshToken = updatedSession.refreshToken;\n }\n\n // Just in case. At this point, the access token should be present\n /* v8 ignore next -- @preserve */\n if (!token) {\n throw new MonoCloudValidationError('Access token not found');\n }\n\n return {\n ...token,\n idToken,\n refreshToken,\n isExpired: token.accessTokenExpiration - 30 < now(),\n };\n }\n\n private async verifyLogoutToken(\n token: string,\n metadata: IssuerMetadata\n ): Promise<JWTPayload> {\n const jwks = createRemoteJWKSet(new URL(metadata.jwks_uri));\n\n const { payload } = await jwtVerify(token, jwks, {\n issuer: metadata.issuer,\n audience: this.options.clientId,\n algorithms: [this.options.idTokenSigningAlg],\n requiredClaims: ['iat'],\n });\n\n if (\n (!payload.sid && !payload.sub) ||\n payload.nonce ||\n !payload.events ||\n typeof payload.events !== 'object'\n ) {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n const event = (payload.events as any)[\n 'http://schemas.openid.net/event/backchannel-logout'\n ];\n\n if (!event || typeof event !== 'object') {\n throw new MonoCloudValidationError('Invalid logout token');\n }\n\n return payload;\n }\n\n private handleCatchAll(error: Error, res: MonoCloudResponse): void {\n // eslint-disable-next-line no-console\n console.error(error);\n res.internalServerError();\n }\n\n private validateOptions(): void {\n if (!this.optionsValidated) {\n this.optionsValidated = true;\n getOptions(this.options);\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monocloud/auth-node-core",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "MonoCloud NodeJS Authentication Core SDK",
5
5
  "keywords": [
6
6
  "monocloud",
@@ -56,7 +56,7 @@
56
56
  "joi": "18.0.2",
57
57
  "jose": "6.1.3",
58
58
  "uuid": "13.0.0",
59
- "@monocloud/auth-core": "0.1.6"
59
+ "@monocloud/auth-core": "0.1.7"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/debug": "4.1.12",