{"version":3,"file":"index.mjs","sources":["../../../src/services/auth/index.ts"],"sourcesContent":["import assert from 'assert/strict';\nimport { has } from 'lodash/fp';\n\nimport { errors } from '@strapi/utils';\nimport type { Common } from '@strapi/types';\nimport type { ParameterizedContext } from 'koa';\n\ninterface AuthenticationResponse {\n  authenticated?: boolean;\n  credentials?: unknown;\n  ability?: unknown;\n  error?: Error | null;\n}\n\ninterface AuthenticationInfo {\n  strategy: Strategy;\n  credentials: unknown;\n  ability: unknown;\n}\n\ninterface Strategy {\n  name: string;\n  authenticate: (ctx: ParameterizedContext) => Promise<AuthenticationResponse>;\n  verify?: (auth: AuthenticationInfo, config: Common.RouteConfig['auth']) => Promise<any>;\n}\n\ninterface Authentication {\n  register: (type: string, strategy: Strategy) => Authentication;\n  authenticate: Common.MiddlewareHandler;\n  verify: (auth: AuthenticationInfo, config?: Common.RouteConfig['auth']) => Promise<any>;\n}\n\nconst INVALID_STRATEGY_MSG =\n  'Invalid auth strategy. Expecting an object with properties {name: string, authenticate: function, verify: function}';\n\nconst validStrategy = (strategy: Strategy) => {\n  assert(has('authenticate', strategy), INVALID_STRATEGY_MSG);\n  assert(typeof strategy.authenticate === 'function', INVALID_STRATEGY_MSG);\n\n  if (has('verify', strategy)) {\n    assert(typeof strategy.verify === 'function', INVALID_STRATEGY_MSG);\n  }\n};\n\nconst createAuthentication = (): Authentication => {\n  const strategies: Record<string, Strategy[]> = {};\n\n  return {\n    register(type, strategy) {\n      validStrategy(strategy);\n\n      if (!strategies[type]) {\n        strategies[type] = [];\n      }\n\n      strategies[type].push(strategy);\n\n      return this;\n    },\n\n    async authenticate(ctx, next) {\n      const route: Common.Route = ctx.state.route;\n\n      // use route strategy\n      const config = route?.config?.auth;\n\n      if (config === false) {\n        return next();\n      }\n\n      const routeStrategies = route.info.type ? strategies[route.info.type] : [];\n      const configStrategies = (config?.strategies ?? routeStrategies ?? []) as Array<\n        string | Strategy\n      >;\n\n      const strategiesToUse: Strategy[] = configStrategies.reduce(\n        (acc, strategy: string | Strategy) => {\n          // Resolve by strategy name\n          if (typeof strategy === 'string') {\n            const routeStrategy = routeStrategies.find((rs) => rs.name === strategy);\n\n            if (routeStrategy) {\n              acc.push(routeStrategy);\n            }\n          }\n\n          // Use the given strategy as is\n          else if (typeof strategy === 'object') {\n            validStrategy(strategy);\n\n            acc.push(strategy);\n          }\n\n          return acc;\n        },\n        [] as Strategy[]\n      );\n\n      for (const strategy of strategiesToUse) {\n        const result = await strategy.authenticate(ctx);\n\n        const { authenticated = false, credentials, ability = null, error = null } = result || {};\n\n        if (error !== null) {\n          return ctx.unauthorized(error);\n        }\n\n        if (authenticated) {\n          ctx.state.isAuthenticated = true;\n          ctx.state.auth = {\n            strategy,\n            credentials,\n            ability,\n          };\n\n          return next();\n        }\n      }\n\n      return ctx.unauthorized('Missing or invalid credentials');\n    },\n\n    async verify(auth, config = {}) {\n      if (config === false) {\n        return;\n      }\n\n      if (!auth) {\n        throw new errors.UnauthorizedError();\n      }\n\n      if (typeof auth.strategy.verify === 'function') {\n        return auth.strategy.verify(auth, config);\n      }\n    },\n  };\n};\n\nexport default createAuthentication;\n"],"names":[],"mappings":";;;AAgCA,MAAM,uBACJ;AAEF,MAAM,gBAAgB,CAAC,aAAuB;AAC5C,SAAO,IAAI,gBAAgB,QAAQ,GAAG,oBAAoB;AAC1D,SAAO,OAAO,SAAS,iBAAiB,YAAY,oBAAoB;AAEpE,MAAA,IAAI,UAAU,QAAQ,GAAG;AAC3B,WAAO,OAAO,SAAS,WAAW,YAAY,oBAAoB;AAAA,EACpE;AACF;AAEA,MAAM,uBAAuB,MAAsB;AACjD,QAAM,aAAyC,CAAA;AAExC,SAAA;AAAA,IACL,SAAS,MAAM,UAAU;AACvB,oBAAc,QAAQ;AAElB,UAAA,CAAC,WAAW,IAAI,GAAG;AACV,mBAAA,IAAI,IAAI;MACrB;AAEW,iBAAA,IAAI,EAAE,KAAK,QAAQ;AAEvB,aAAA;AAAA,IACT;AAAA,IAEA,MAAM,aAAa,KAAK,MAAM;AACtB,YAAA,QAAsB,IAAI,MAAM;AAGhC,YAAA,SAAS,OAAO,QAAQ;AAE9B,UAAI,WAAW,OAAO;AACpB,eAAO,KAAK;AAAA,MACd;AAEM,YAAA,kBAAkB,MAAM,KAAK,OAAO,WAAW,MAAM,KAAK,IAAI,IAAI;AACxE,YAAM,mBAAoB,QAAQ,cAAc,mBAAmB,CAAA;AAInE,YAAM,kBAA8B,iBAAiB;AAAA,QACnD,CAAC,KAAK,aAAgC;AAEhC,cAAA,OAAO,aAAa,UAAU;AAChC,kBAAM,gBAAgB,gBAAgB,KAAK,CAAC,OAAO,GAAG,SAAS,QAAQ;AAEvE,gBAAI,eAAe;AACjB,kBAAI,KAAK,aAAa;AAAA,YACxB;AAAA,UAAA,WAIO,OAAO,aAAa,UAAU;AACrC,0BAAc,QAAQ;AAEtB,gBAAI,KAAK,QAAQ;AAAA,UACnB;AAEO,iBAAA;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MAAA;AAGH,iBAAW,YAAY,iBAAiB;AACtC,cAAM,SAAS,MAAM,SAAS,aAAa,GAAG;AAExC,cAAA,EAAE,gBAAgB,OAAO,aAAa,UAAU,MAAM,QAAQ,KAAA,IAAS,UAAU;AAEvF,YAAI,UAAU,MAAM;AACX,iBAAA,IAAI,aAAa,KAAK;AAAA,QAC/B;AAEA,YAAI,eAAe;AACjB,cAAI,MAAM,kBAAkB;AAC5B,cAAI,MAAM,OAAO;AAAA,YACf;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAGF,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAEO,aAAA,IAAI,aAAa,gCAAgC;AAAA,IAC1D;AAAA,IAEA,MAAM,OAAO,MAAM,SAAS,IAAI;AAC9B,UAAI,WAAW,OAAO;AACpB;AAAA,MACF;AAEA,UAAI,CAAC,MAAM;AACH,cAAA,IAAI,OAAO;MACnB;AAEA,UAAI,OAAO,KAAK,SAAS,WAAW,YAAY;AAC9C,eAAO,KAAK,SAAS,OAAO,MAAM,MAAM;AAAA,MAC1C;AAAA,IACF;AAAA,EAAA;AAEJ;"}