text: const Joi = require('joi');
  const crypto = require('crypto');
  const { defaultState: getLoginState } = require('./hooks/getLoginState');
  const isHttps = /^https:/i;
  
  const defaultSessionIdGenerator = () => crypto.randomBytes(16).toString('hex');
  
  const paramsSchema = Joi.object({
    secret: Joi.alternatives([
      Joi.string().min(8),
      Joi.binary().min(8),
      Joi.array().items(Joi.string().min(8), Joi.binary().min(8)),
    ]).required(),
    session: Joi.object({
      rolling: Joi.boolean().optional().default(true),
      rollingDuration: Joi.when(Joi.ref('rolling'), {
        is: true,
        then: Joi.number().integer().messages({
          'number.base':
            '"session.rollingDuration" must be provided an integer value when "session.rolling" is true',
        }),
        otherwise: Joi.boolean().valid(false).messages({
          'any.only':
            '"session.rollingDuration" must be false when "session.rolling" is disabled',
        }),
      })
        .optional()
        .default((parent) => (parent.rolling ? 24 * 60 * 60 : false)), // 1 day when rolling is enabled, else false
      absoluteDuration: Joi.when(Joi.ref('rolling'), {
        is: false,
        then: Joi.number().integer().messages({
          'number.base':
            '"session.absoluteDuration" must be provided an integer value when "session.rolling" is false',
        }),
        otherwise: Joi.alternatives([
          Joi.number().integer(),
          Joi.boolean().valid(false),
        ]),
      })
        .optional()
        .default(7 * 24 * 60 * 60), // 7 days,
      name: Joi.string().token().optional().default('appSession'),
      store: Joi.object().optional(),
      genid: Joi.function()
        .maxArity(1)
        .optional()
        .default(() => defaultSessionIdGenerator),
      cookie: Joi.object({
        domain: Joi.string().optional(),
        transient: Joi.boolean().optional().default(false),
        httpOnly: Joi.boolean().optional().default(true),
        sameSite: Joi.string()
          .valid('Lax', 'Strict', 'None')
          .optional()
          .default('Lax'),
        secure: Joi.when(Joi.ref('/baseURL'), {
          is: Joi.string().pattern(isHttps),
          then: Joi.boolean()
            .default(true)
            .custom((value, { warn }) => {
              if (!value) warn('insecure.cookie');
              return value;
            })
            .messages({
              'insecure.cookie':
                "Setting your cookie to insecure when over https is not recommended, I hope you know what you're doing.",
            }),
          otherwise: Joi.boolean().valid(false).default(false).messages({
            'any.only':
              'Cookies set with the `Secure` property wont be attached to http requests',
          }),
        }),
        path: Joi.string().uri({ relativeOnly: true }).optional(),
      })
        .default()
        .unknown(false),
    })
      .default()
      .unknown(false),
    auth0Logout: Joi.boolean().optional().default(false),
    tokenEndpointParams: Joi.object().optional(),
    authorizationParams: Joi.object({
      response_type: Joi.string()
        .optional()
        .valid('id_token', 'code id_token', 'code')
        .default('id_token'),
      scope: Joi.string()
        .optional()
        .pattern(/\bopenid\b/, 'contains openid')
        .default('openid profile email'),
      response_mode: Joi.string()
        .optional()
        .when('response_type', {
          is: 'code',
          then: Joi.valid('query', 'form_post'),
          otherwise: Joi.valid('form_post').default('form_post'),
        }),
    })
      .optional()
      .unknown(true)
      .default(),
    baseURL: Joi.string()
      .uri()
      .required()
      .when(Joi.ref('authorizationParams.response_mode'), {
        is: 'form_post',
        then: Joi.string().pattern(isHttps).rule({
          warn: true,
          message: `Using 'form_post' for response_mode may cause issues for you logging in over http, see https://github.com/auth0/express-openid-connect/blob/master/FAQ.md`,
        }),
      }),
    clientID: Joi.string().required(),
    clientSecret: Joi.string()
      .when(
        Joi.ref('authorizationParams.response_type', {
          adjust: (value) => value && value.includes('code'),
        }),
        {
          is: true,
          then: Joi.string().required().messages({
            'any.required':
              '"clientSecret" is required for a response_type that includes code',
          }),
        }
      )
      .when(
        Joi.ref('idTokenSigningAlg', {
          adjust: (value) => value && value.startsWith('HS'),
        }),
        {
          is: true,
          then: Joi.string().required().messages({
            'any.required':
              '"clientSecret" is required for ID tokens with HMAC based algorithms',
          }),
        }
      ),
    clockTolerance: Joi.number().optional().default(60),
    enableTelemetry: Joi.boolean().optional().default(true),
    errorOnRequiredAuth: Joi.boolean().optional().default(false),
    attemptSilentLogin: Joi.boolean().optional().default(false),
    getLoginState: Joi.function()
      .optional()
      .default(() => getLoginState),
    afterCallback: Joi.function().optional(),
    identityClaimFilter: Joi.array()
      .optional()
      .default([
        'aud',
        'iss',
        'iat',
        'exp',
        'nbf',
        'nonce',
        'azp',
        'auth_time',
        's_hash',
        'at_hash',
        'c_hash',
      ]),
    idpLogout: Joi.boolean()
      .optional()
      .default((parent) => parent.auth0Logout || false),
    idTokenSigningAlg: Joi.string()
      .insensitive()
      .not('none')
      .optional()
      .default('RS256'),
    issuerBaseURL: Joi.string().uri().required(),
    legacySameSiteCookie: Joi.boolean().optional().default(true),
    authRequired: Joi.boolean().optional().default(true),
    routes: Joi.object({
      login: Joi.alternatives([
        Joi.string().uri({ relativeOnly: true }),
        Joi.boolean().valid(false),
      ]).default('/login'),
      logout: Joi.alternatives([
        Joi.string().uri({ relativeOnly: true }),
        Joi.boolean().valid(false),
      ]).default('/logout'),
      callback: Joi.string().uri({ relativeOnly: true }).default('/callback'),
      postLogoutRedirect: Joi.string().uri({ allowRelative: true }).default(''),
    })
      .default()
      .unknown(false),
    clientAuthMethod: Joi.string()
      .valid('client_secret_basic', 'client_secret_post', 'none')
      .optional()
      .default((parent) => {
        return parent.authorizationParams.response_type === 'id_token'
          ? 'none'
          : 'client_secret_basic';
      }),
    httpTimeout: Joi.number().optional().min(500).default(5000),
  });
  
  module.exports.get = function (config = {}) {
    config = {
      secret: process.env.SECRET,
      issuerBaseURL: process.env.ISSUER_BASE_URL,
      baseURL: process.env.BASE_URL,
      clientID: process.env.CLIENT_ID,
      clientSecret: process.env.CLIENT_SECRET,
      ...config,
    };
  
    const { value, error, warning } = paramsSchema.validate(config);
    if (error) {
      throw new TypeError(error.details[0].message);
    }
    if (warning) {
      console.warn(warning.message);
    }
    return value;
  };
  