@strapi/plugin-users-permissions 5.52.2 → 5.53.0
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/server/controllers/auth.js +8 -2
- package/dist/server/controllers/auth.js.map +1 -1
- package/dist/server/controllers/auth.mjs +8 -2
- package/dist/server/controllers/auth.mjs.map +1 -1
- package/dist/server/graphql/mutations/auth/change-password.js +6 -3
- package/dist/server/graphql/mutations/auth/change-password.js.map +1 -1
- package/dist/server/graphql/mutations/auth/change-password.mjs +6 -3
- package/dist/server/graphql/mutations/auth/change-password.mjs.map +1 -1
- package/dist/server/graphql/mutations/auth/forgot-password.js +6 -3
- package/dist/server/graphql/mutations/auth/forgot-password.js.map +1 -1
- package/dist/server/graphql/mutations/auth/forgot-password.mjs +6 -3
- package/dist/server/graphql/mutations/auth/forgot-password.mjs.map +1 -1
- package/dist/server/graphql/mutations/auth/login.js +9 -6
- package/dist/server/graphql/mutations/auth/login.js.map +1 -1
- package/dist/server/graphql/mutations/auth/login.mjs +9 -6
- package/dist/server/graphql/mutations/auth/login.mjs.map +1 -1
- package/dist/server/graphql/mutations/auth/rate-limit.js +63 -0
- package/dist/server/graphql/mutations/auth/rate-limit.js.map +1 -0
- package/dist/server/graphql/mutations/auth/rate-limit.mjs +61 -0
- package/dist/server/graphql/mutations/auth/rate-limit.mjs.map +1 -0
- package/dist/server/graphql/mutations/auth/register.js +6 -3
- package/dist/server/graphql/mutations/auth/register.js.map +1 -1
- package/dist/server/graphql/mutations/auth/register.mjs +6 -3
- package/dist/server/graphql/mutations/auth/register.mjs.map +1 -1
- package/dist/server/graphql/mutations/auth/reset-password.js +6 -3
- package/dist/server/graphql/mutations/auth/reset-password.js.map +1 -1
- package/dist/server/graphql/mutations/auth/reset-password.mjs +6 -3
- package/dist/server/graphql/mutations/auth/reset-password.mjs.map +1 -1
- package/dist/server/middlewares/rateLimit.js +1 -1
- package/dist/server/middlewares/rateLimit.js.map +1 -1
- package/dist/server/middlewares/rateLimit.mjs +1 -1
- package/dist/server/middlewares/rateLimit.mjs.map +1 -1
- package/dist/server/services/providers-registry.js +80 -19
- package/dist/server/services/providers-registry.js.map +1 -1
- package/dist/server/services/providers-registry.mjs +80 -19
- package/dist/server/services/providers-registry.mjs.map +1 -1
- package/dist/server/services/providers.js +12 -8
- package/dist/server/services/providers.js.map +1 -1
- package/dist/server/services/providers.mjs +12 -8
- package/dist/server/services/providers.mjs.map +1 -1
- package/dist/server/services/user.js +7 -7
- package/dist/server/services/user.js.map +1 -1
- package/dist/server/services/user.mjs +7 -7
- package/dist/server/services/user.mjs.map +1 -1
- package/dist/server/utils/oauth-connect/index.js +11 -6
- package/dist/server/utils/oauth-connect/index.js.map +1 -1
- package/dist/server/utils/oauth-connect/index.mjs +11 -6
- package/dist/server/utils/oauth-connect/index.mjs.map +1 -1
- package/dist/server/utils/trim-grant-session-response.js +67 -0
- package/dist/server/utils/trim-grant-session-response.js.map +1 -0
- package/dist/server/utils/trim-grant-session-response.mjs +65 -0
- package/dist/server/utils/trim-grant-session-response.mjs.map +1 -0
- package/package.json +4 -4
- package/server/src/controllers/auth.js +13 -2
- package/server/src/graphql/mutations/auth/change-password.js +5 -5
- package/server/src/graphql/mutations/auth/forgot-password.js +5 -5
- package/server/src/graphql/mutations/auth/login.js +10 -6
- package/server/src/graphql/mutations/auth/rate-limit.js +62 -0
- package/server/src/graphql/mutations/auth/register.js +5 -5
- package/server/src/graphql/mutations/auth/reset-password.js +5 -5
- package/server/src/middlewares/rateLimit.js +1 -1
- package/server/src/services/providers-registry.js +99 -23
- package/server/src/services/providers.js +9 -7
- package/server/src/services/user.js +15 -5
- package/server/src/utils/oauth-connect/index.js +12 -6
- package/server/src/utils/trim-grant-session-response.js +70 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import require$$0 from 'lodash/fp';
|
|
2
2
|
import { __require as requireUtils } from '../../utils.mjs';
|
|
3
|
+
import { __require as requireRateLimit } from './rate-limit.mjs';
|
|
3
4
|
|
|
4
5
|
var resetPassword;
|
|
5
6
|
var hasRequiredResetPassword;
|
|
@@ -8,8 +9,10 @@ function requireResetPassword() {
|
|
|
8
9
|
hasRequiredResetPassword = 1;
|
|
9
10
|
const { toPlainObject } = require$$0;
|
|
10
11
|
const { checkBadRequest } = requireUtils();
|
|
12
|
+
const { createRateLimitRunner } = requireRateLimit();
|
|
11
13
|
resetPassword = ({ nexus, strapi })=>{
|
|
12
14
|
const { nonNull } = nexus;
|
|
15
|
+
const runRateLimit = createRateLimitRunner(strapi, '/auth/reset-password');
|
|
13
16
|
return {
|
|
14
17
|
type: 'UsersPermissionsLoginPayload',
|
|
15
18
|
args: {
|
|
@@ -20,9 +23,9 @@ function requireResetPassword() {
|
|
|
20
23
|
description: 'Reset user password. Confirm with a code (resetToken from forgotPassword)',
|
|
21
24
|
async resolve (parent, args, context) {
|
|
22
25
|
const { koaContext } = context;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
const output = await runRateLimit(koaContext, {
|
|
27
|
+
body: toPlainObject(args)
|
|
28
|
+
}, (ctx)=>strapi.plugin('users-permissions').controller('auth').resetPassword(ctx));
|
|
26
29
|
checkBadRequest(output);
|
|
27
30
|
return {
|
|
28
31
|
user: output.user || output,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset-password.mjs","sources":["../../../../../server/src/graphql/mutations/auth/reset-password.js"],"sourcesContent":["'use strict';\n\nconst { toPlainObject } = require('lodash/fp');\n\nconst { checkBadRequest } = require('../../utils');\n\nmodule.exports = ({ nexus, strapi }) => {\n const { nonNull } = nexus;\n\n return {\n type: 'UsersPermissionsLoginPayload',\n\n args: {\n password: nonNull('String'),\n passwordConfirmation: nonNull('String'),\n code: nonNull('String'),\n },\n\n description: 'Reset user password. Confirm with a code (resetToken from forgotPassword)',\n\n async resolve(parent, args, context) {\n const { koaContext } = context;\n\n koaContext
|
|
1
|
+
{"version":3,"file":"reset-password.mjs","sources":["../../../../../server/src/graphql/mutations/auth/reset-password.js"],"sourcesContent":["'use strict';\n\nconst { toPlainObject } = require('lodash/fp');\n\nconst { checkBadRequest } = require('../../utils');\nconst { createRateLimitRunner } = require('./rate-limit');\n\nmodule.exports = ({ nexus, strapi }) => {\n const { nonNull } = nexus;\n const runRateLimit = createRateLimitRunner(strapi, '/auth/reset-password');\n\n return {\n type: 'UsersPermissionsLoginPayload',\n\n args: {\n password: nonNull('String'),\n passwordConfirmation: nonNull('String'),\n code: nonNull('String'),\n },\n\n description: 'Reset user password. Confirm with a code (resetToken from forgotPassword)',\n\n async resolve(parent, args, context) {\n const { koaContext } = context;\n\n const output = await runRateLimit(koaContext, { body: toPlainObject(args) }, (ctx) =>\n strapi.plugin('users-permissions').controller('auth').resetPassword(ctx)\n );\n\n checkBadRequest(output);\n\n return {\n user: output.user || output,\n jwt: output.jwt,\n };\n },\n };\n};\n"],"names":["toPlainObject","require$$0","checkBadRequest","require$$1","createRateLimitRunner","require$$2","resetPassword","nexus","strapi","nonNull","runRateLimit","type","args","password","passwordConfirmation","code","description","resolve","parent","context","koaContext","output","body","ctx","plugin","controller","user","jwt"],"mappings":";;;;;;;;;IAEA,MAAM,EAAEA,aAAa,EAAE,GAAGC,UAAAA;IAE1B,MAAM,EAAEC,eAAe,EAAE,GAAGC,YAAAA,EAAAA;IAC5B,MAAM,EAAEC,qBAAqB,EAAE,GAAGC,gBAAAA,EAAAA;AAElCC,IAAAA,aAAAA,GAAiB,CAAC,EAAEC,KAAK,EAAEC,MAAM,EAAE,GAAA;QACjC,MAAM,EAAEC,OAAO,EAAE,GAAGF,KAAAA;QACpB,MAAMG,YAAAA,GAAeN,sBAAsBI,MAAAA,EAAQ,sBAAA,CAAA;QAEnD,OAAO;YACLG,IAAAA,EAAM,8BAAA;YAENC,IAAAA,EAAM;AACJC,gBAAAA,QAAAA,EAAUJ,OAAAA,CAAQ,QAAA,CAAA;AAClBK,gBAAAA,oBAAAA,EAAsBL,OAAAA,CAAQ,QAAA,CAAA;AAC9BM,gBAAAA,IAAAA,EAAMN,OAAAA,CAAQ,QAAA;AACpB,aAAA;YAEIO,WAAAA,EAAa,2EAAA;AAEb,YAAA,MAAMC,OAAAA,CAAAA,CAAQC,MAAM,EAAEN,IAAI,EAAEO,OAAO,EAAA;gBACjC,MAAM,EAAEC,UAAU,EAAE,GAAGD,OAAAA;gBAEvB,MAAME,MAAAA,GAAS,MAAMX,YAAAA,CAAaU,UAAAA,EAAY;AAAEE,oBAAAA,IAAAA,EAAMtB,aAAAA,CAAcY,IAAAA;iBAAK,EAAI,CAACW,GAAAA,GAC5Ef,MAAAA,CAAOgB,MAAM,CAAC,qBAAqBC,UAAU,CAAC,MAAA,CAAA,CAAQnB,aAAa,CAACiB,GAAAA,CAAAA,CAAAA;gBAGtErB,eAAAA,CAAgBmB,MAAAA,CAAAA;gBAEhB,OAAO;oBACLK,IAAAA,EAAML,MAAAA,CAAOK,IAAI,IAAIL,MAAAA;AACrBM,oBAAAA,GAAAA,EAAKN,OAAOM;AACpB,iBAAA;AACA,YAAA;AACA,SAAA;AACA,IAAA,CAAA;;;;;;"}
|
|
@@ -59,7 +59,7 @@ function requireRateLimit() {
|
|
|
59
59
|
* lower-cased, trailing slashes removed so `/api/auth/local` and
|
|
60
60
|
* `/api/auth/local/` share one bucket.
|
|
61
61
|
*/ const normalizeRequestPathForRateLimit = (requestPath)=>{
|
|
62
|
-
const normalized = path.normalize(requestPath);
|
|
62
|
+
const normalized = path.posix.normalize(requestPath);
|
|
63
63
|
const lower = toLower(normalized);
|
|
64
64
|
return lower.replace(/\/+$/, '') || '/';
|
|
65
65
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimit.js","sources":["../../../server/src/middlewares/rateLimit.js"],"sourcesContent":["'use strict';\n\nconst path = require('path');\nconst utils = require('@strapi/utils');\nconst { isString, has, toLower } = require('lodash/fp');\n\nconst { RateLimitError } = utils.errors;\n\n/**\n * Routes where the rate-limit key MUST NOT include a user identifier\n * derived from `ctx.request.body.email`.\n *\n * On these routes the request body either has no `email` field\n * (e.g. /auth/local uses `identifier`, /auth/reset-password uses\n * `code`, /auth/change-password uses `currentPassword`) or the\n * field is not part of the route contract. Including the\n * attacker-controlled `body.email` in the rate-limit key on these\n * routes lets a caller obtain a fresh key on every request by\n * varying that field, effectively bypassing per-IP throttling.\n *\n * Comparison uses endsWith so the check is stable under any router\n * mount prefix (e.g. `/api/auth/local`).\n *\n * @see https://github.com/strapi/strapi/security/advisories/GHSA-7mqx-wwh4-f9fw\n *\n * When adding a new `rateLimit`-protected auth route whose body does not\n * use `email` as the real identifier, add its path suffix here (or an\n * equivalent `routeUsesEmailIdentifier` rule) so the key cannot be split\n * with arbitrary `body.email` values.\n */\nconst ROUTES_WITHOUT_IDENTIFIER = ['/auth/local', '/auth/reset-password', '/auth/change-password'];\n\nconst isOAuthCallbackPath = (requestPath) => requestPath.includes('/connect/');\n\nconst routeUsesEmailIdentifier = (requestPath) => {\n if (isOAuthCallbackPath(requestPath)) {\n return false;\n }\n\n return !ROUTES_WITHOUT_IDENTIFIER.some((route) => requestPath.endsWith(route));\n};\n\n/**\n * Paths suitable for route matching and prefix keys: POSIX-normalized,\n * lower-cased, trailing slashes removed so `/api/auth/local` and\n * `/api/auth/local/` share one bucket.\n */\nconst normalizeRequestPathForRateLimit = (requestPath) => {\n const normalized = path.normalize(requestPath);\n const lower = toLower(normalized);\n return lower.replace(/\\/+$/, '') || '/';\n};\n\nconst getEmailIdentifierForKey = (body) => {\n if (!body || !isString(body.email) || body.email === '') {\n return 'unknownIdentifier';\n }\n\n return toLower(body.email);\n};\n\nconst buildPrefixKey = (ctx) => {\n let requestPath;\n if (!isString(ctx.request.path)) {\n requestPath = 'invalidPath';\n } else {\n requestPath = normalizeRequestPathForRateLimit(ctx.request.path);\n if (requestPath === '.' || requestPath === '..') {\n requestPath = 'invalidPath';\n }\n }\n\n if (!routeUsesEmailIdentifier(requestPath)) {\n return `noIdentifier:${requestPath}:${ctx.request.ip}`;\n }\n\n const userIdentifier = getEmailIdentifierForKey(ctx.request.body);\n return `${userIdentifier}:${requestPath}:${ctx.request.ip}`;\n};\n\nconst buildRateLimitLoadConfig = (ctx, rateLimitConfig, routeMiddlewareConfig) => {\n return {\n interval: { min: 5 },\n max: 5,\n ...rateLimitConfig,\n ...routeMiddlewareConfig,\n handler() {\n throw new RateLimitError();\n },\n prefixKey: buildPrefixKey(ctx),\n };\n};\n\nmodule.exports =\n (config, { strapi }) =>\n async (ctx, next) => {\n let rateLimitConfig = strapi.config.get('plugin::users-permissions.ratelimit');\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const loadConfig = buildRateLimitLoadConfig(ctx, rateLimitConfig, config);\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n\nmodule.exports.buildPrefixKey = buildPrefixKey;\nmodule.exports.ROUTES_WITHOUT_IDENTIFIER = ROUTES_WITHOUT_IDENTIFIER;\nmodule.exports.normalizeRequestPathForRateLimit = normalizeRequestPathForRateLimit;\nmodule.exports.buildRateLimitLoadConfig = buildRateLimitLoadConfig;\n"],"names":["path","require$$0","utils","require$$1","isString","has","toLower","require$$2","RateLimitError","errors","ROUTES_WITHOUT_IDENTIFIER","isOAuthCallbackPath","requestPath","includes","routeUsesEmailIdentifier","some","route","endsWith","normalizeRequestPathForRateLimit","normalized","normalize","lower","replace","getEmailIdentifierForKey","body","email","buildPrefixKey","ctx","request","ip","userIdentifier","buildRateLimitLoadConfig","rateLimitConfig","routeMiddlewareConfig","interval","min","max","handler","prefixKey","rateLimitModule","exports","config","strapi","next","get","enabled","rateLimit","require$$3","RateLimit","loadConfig","middleware"],"mappings":";;;;;;;;;;;;;;;;;;;AAEA,IAAA,MAAMA,IAAAA,GAAOC,6BAAAA;AACb,IAAA,MAAMC,KAAAA,GAAQC,2BAAAA;AACd,IAAA,MAAM,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,OAAO,EAAE,GAAGC,2BAAAA;AAEnC,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGN,MAAMO,MAAM;AAEvC;;;;;;;;;;;;;;;;;;;;;AAqBA,KACA,MAAMC,yBAAAA,GAA4B;AAAC,QAAA,aAAA;AAAe,QAAA,sBAAA;AAAwB,QAAA;AAAwB,KAAA;AAElG,IAAA,MAAMC,mBAAAA,GAAsB,CAACC,WAAAA,GAAgBA,WAAAA,CAAYC,QAAQ,CAAC,WAAA,CAAA;AAElE,IAAA,MAAMC,2BAA2B,CAACF,WAAAA,GAAAA;AAChC,QAAA,IAAID,oBAAoBC,WAAAA,CAAAA,EAAc;YACpC,OAAO,KAAA;AACX,QAAA;QAEE,OAAO,CAACF,0BAA0BK,IAAI,CAAC,CAACC,KAAAA,GAAUJ,WAAAA,CAAYK,QAAQ,CAACD,KAAAA,CAAAA,CAAAA;AACzE,IAAA,CAAA;AAEA;;;;KAKA,MAAME,mCAAmC,CAACN,WAAAA,GAAAA;
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sources":["../../../server/src/middlewares/rateLimit.js"],"sourcesContent":["'use strict';\n\nconst path = require('path');\nconst utils = require('@strapi/utils');\nconst { isString, has, toLower } = require('lodash/fp');\n\nconst { RateLimitError } = utils.errors;\n\n/**\n * Routes where the rate-limit key MUST NOT include a user identifier\n * derived from `ctx.request.body.email`.\n *\n * On these routes the request body either has no `email` field\n * (e.g. /auth/local uses `identifier`, /auth/reset-password uses\n * `code`, /auth/change-password uses `currentPassword`) or the\n * field is not part of the route contract. Including the\n * attacker-controlled `body.email` in the rate-limit key on these\n * routes lets a caller obtain a fresh key on every request by\n * varying that field, effectively bypassing per-IP throttling.\n *\n * Comparison uses endsWith so the check is stable under any router\n * mount prefix (e.g. `/api/auth/local`).\n *\n * @see https://github.com/strapi/strapi/security/advisories/GHSA-7mqx-wwh4-f9fw\n *\n * When adding a new `rateLimit`-protected auth route whose body does not\n * use `email` as the real identifier, add its path suffix here (or an\n * equivalent `routeUsesEmailIdentifier` rule) so the key cannot be split\n * with arbitrary `body.email` values.\n */\nconst ROUTES_WITHOUT_IDENTIFIER = ['/auth/local', '/auth/reset-password', '/auth/change-password'];\n\nconst isOAuthCallbackPath = (requestPath) => requestPath.includes('/connect/');\n\nconst routeUsesEmailIdentifier = (requestPath) => {\n if (isOAuthCallbackPath(requestPath)) {\n return false;\n }\n\n return !ROUTES_WITHOUT_IDENTIFIER.some((route) => requestPath.endsWith(route));\n};\n\n/**\n * Paths suitable for route matching and prefix keys: POSIX-normalized,\n * lower-cased, trailing slashes removed so `/api/auth/local` and\n * `/api/auth/local/` share one bucket.\n */\nconst normalizeRequestPathForRateLimit = (requestPath) => {\n const normalized = path.posix.normalize(requestPath);\n const lower = toLower(normalized);\n return lower.replace(/\\/+$/, '') || '/';\n};\n\nconst getEmailIdentifierForKey = (body) => {\n if (!body || !isString(body.email) || body.email === '') {\n return 'unknownIdentifier';\n }\n\n return toLower(body.email);\n};\n\nconst buildPrefixKey = (ctx) => {\n let requestPath;\n if (!isString(ctx.request.path)) {\n requestPath = 'invalidPath';\n } else {\n requestPath = normalizeRequestPathForRateLimit(ctx.request.path);\n if (requestPath === '.' || requestPath === '..') {\n requestPath = 'invalidPath';\n }\n }\n\n if (!routeUsesEmailIdentifier(requestPath)) {\n return `noIdentifier:${requestPath}:${ctx.request.ip}`;\n }\n\n const userIdentifier = getEmailIdentifierForKey(ctx.request.body);\n return `${userIdentifier}:${requestPath}:${ctx.request.ip}`;\n};\n\nconst buildRateLimitLoadConfig = (ctx, rateLimitConfig, routeMiddlewareConfig) => {\n return {\n interval: { min: 5 },\n max: 5,\n ...rateLimitConfig,\n ...routeMiddlewareConfig,\n handler() {\n throw new RateLimitError();\n },\n prefixKey: buildPrefixKey(ctx),\n };\n};\n\nmodule.exports =\n (config, { strapi }) =>\n async (ctx, next) => {\n let rateLimitConfig = strapi.config.get('plugin::users-permissions.ratelimit');\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const loadConfig = buildRateLimitLoadConfig(ctx, rateLimitConfig, config);\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n\nmodule.exports.buildPrefixKey = buildPrefixKey;\nmodule.exports.ROUTES_WITHOUT_IDENTIFIER = ROUTES_WITHOUT_IDENTIFIER;\nmodule.exports.normalizeRequestPathForRateLimit = normalizeRequestPathForRateLimit;\nmodule.exports.buildRateLimitLoadConfig = buildRateLimitLoadConfig;\n"],"names":["path","require$$0","utils","require$$1","isString","has","toLower","require$$2","RateLimitError","errors","ROUTES_WITHOUT_IDENTIFIER","isOAuthCallbackPath","requestPath","includes","routeUsesEmailIdentifier","some","route","endsWith","normalizeRequestPathForRateLimit","normalized","posix","normalize","lower","replace","getEmailIdentifierForKey","body","email","buildPrefixKey","ctx","request","ip","userIdentifier","buildRateLimitLoadConfig","rateLimitConfig","routeMiddlewareConfig","interval","min","max","handler","prefixKey","rateLimitModule","exports","config","strapi","next","get","enabled","rateLimit","require$$3","RateLimit","loadConfig","middleware"],"mappings":"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"}
|
|
@@ -50,7 +50,7 @@ function requireRateLimit() {
|
|
|
50
50
|
* lower-cased, trailing slashes removed so `/api/auth/local` and
|
|
51
51
|
* `/api/auth/local/` share one bucket.
|
|
52
52
|
*/ const normalizeRequestPathForRateLimit = (requestPath)=>{
|
|
53
|
-
const normalized = path.normalize(requestPath);
|
|
53
|
+
const normalized = path.posix.normalize(requestPath);
|
|
54
54
|
const lower = toLower(normalized);
|
|
55
55
|
return lower.replace(/\/+$/, '') || '/';
|
|
56
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimit.mjs","sources":["../../../server/src/middlewares/rateLimit.js"],"sourcesContent":["'use strict';\n\nconst path = require('path');\nconst utils = require('@strapi/utils');\nconst { isString, has, toLower } = require('lodash/fp');\n\nconst { RateLimitError } = utils.errors;\n\n/**\n * Routes where the rate-limit key MUST NOT include a user identifier\n * derived from `ctx.request.body.email`.\n *\n * On these routes the request body either has no `email` field\n * (e.g. /auth/local uses `identifier`, /auth/reset-password uses\n * `code`, /auth/change-password uses `currentPassword`) or the\n * field is not part of the route contract. Including the\n * attacker-controlled `body.email` in the rate-limit key on these\n * routes lets a caller obtain a fresh key on every request by\n * varying that field, effectively bypassing per-IP throttling.\n *\n * Comparison uses endsWith so the check is stable under any router\n * mount prefix (e.g. `/api/auth/local`).\n *\n * @see https://github.com/strapi/strapi/security/advisories/GHSA-7mqx-wwh4-f9fw\n *\n * When adding a new `rateLimit`-protected auth route whose body does not\n * use `email` as the real identifier, add its path suffix here (or an\n * equivalent `routeUsesEmailIdentifier` rule) so the key cannot be split\n * with arbitrary `body.email` values.\n */\nconst ROUTES_WITHOUT_IDENTIFIER = ['/auth/local', '/auth/reset-password', '/auth/change-password'];\n\nconst isOAuthCallbackPath = (requestPath) => requestPath.includes('/connect/');\n\nconst routeUsesEmailIdentifier = (requestPath) => {\n if (isOAuthCallbackPath(requestPath)) {\n return false;\n }\n\n return !ROUTES_WITHOUT_IDENTIFIER.some((route) => requestPath.endsWith(route));\n};\n\n/**\n * Paths suitable for route matching and prefix keys: POSIX-normalized,\n * lower-cased, trailing slashes removed so `/api/auth/local` and\n * `/api/auth/local/` share one bucket.\n */\nconst normalizeRequestPathForRateLimit = (requestPath) => {\n const normalized = path.normalize(requestPath);\n const lower = toLower(normalized);\n return lower.replace(/\\/+$/, '') || '/';\n};\n\nconst getEmailIdentifierForKey = (body) => {\n if (!body || !isString(body.email) || body.email === '') {\n return 'unknownIdentifier';\n }\n\n return toLower(body.email);\n};\n\nconst buildPrefixKey = (ctx) => {\n let requestPath;\n if (!isString(ctx.request.path)) {\n requestPath = 'invalidPath';\n } else {\n requestPath = normalizeRequestPathForRateLimit(ctx.request.path);\n if (requestPath === '.' || requestPath === '..') {\n requestPath = 'invalidPath';\n }\n }\n\n if (!routeUsesEmailIdentifier(requestPath)) {\n return `noIdentifier:${requestPath}:${ctx.request.ip}`;\n }\n\n const userIdentifier = getEmailIdentifierForKey(ctx.request.body);\n return `${userIdentifier}:${requestPath}:${ctx.request.ip}`;\n};\n\nconst buildRateLimitLoadConfig = (ctx, rateLimitConfig, routeMiddlewareConfig) => {\n return {\n interval: { min: 5 },\n max: 5,\n ...rateLimitConfig,\n ...routeMiddlewareConfig,\n handler() {\n throw new RateLimitError();\n },\n prefixKey: buildPrefixKey(ctx),\n };\n};\n\nmodule.exports =\n (config, { strapi }) =>\n async (ctx, next) => {\n let rateLimitConfig = strapi.config.get('plugin::users-permissions.ratelimit');\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const loadConfig = buildRateLimitLoadConfig(ctx, rateLimitConfig, config);\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n\nmodule.exports.buildPrefixKey = buildPrefixKey;\nmodule.exports.ROUTES_WITHOUT_IDENTIFIER = ROUTES_WITHOUT_IDENTIFIER;\nmodule.exports.normalizeRequestPathForRateLimit = normalizeRequestPathForRateLimit;\nmodule.exports.buildRateLimitLoadConfig = buildRateLimitLoadConfig;\n"],"names":["path","require$$0","utils","require$$1","isString","has","toLower","require$$2","RateLimitError","errors","ROUTES_WITHOUT_IDENTIFIER","isOAuthCallbackPath","requestPath","includes","routeUsesEmailIdentifier","some","route","endsWith","normalizeRequestPathForRateLimit","normalized","normalize","lower","replace","getEmailIdentifierForKey","body","email","buildPrefixKey","ctx","request","ip","userIdentifier","buildRateLimitLoadConfig","rateLimitConfig","routeMiddlewareConfig","interval","min","max","handler","prefixKey","rateLimitModule","exports","config","strapi","next","get","enabled","rateLimit","require$$3","RateLimit","loadConfig","middleware"],"mappings":";;;;;;;;;;AAEA,IAAA,MAAMA,IAAAA,GAAOC,YAAAA;AACb,IAAA,MAAMC,KAAAA,GAAQC,UAAAA;AACd,IAAA,MAAM,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,OAAO,EAAE,GAAGC,UAAAA;AAEnC,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGN,MAAMO,MAAM;AAEvC;;;;;;;;;;;;;;;;;;;;;AAqBA,KACA,MAAMC,yBAAAA,GAA4B;AAAC,QAAA,aAAA;AAAe,QAAA,sBAAA;AAAwB,QAAA;AAAwB,KAAA;AAElG,IAAA,MAAMC,mBAAAA,GAAsB,CAACC,WAAAA,GAAgBA,WAAAA,CAAYC,QAAQ,CAAC,WAAA,CAAA;AAElE,IAAA,MAAMC,2BAA2B,CAACF,WAAAA,GAAAA;AAChC,QAAA,IAAID,oBAAoBC,WAAAA,CAAAA,EAAc;YACpC,OAAO,KAAA;AACX,QAAA;QAEE,OAAO,CAACF,0BAA0BK,IAAI,CAAC,CAACC,KAAAA,GAAUJ,WAAAA,CAAYK,QAAQ,CAACD,KAAAA,CAAAA,CAAAA;AACzE,IAAA,CAAA;AAEA;;;;KAKA,MAAME,mCAAmC,CAACN,WAAAA,GAAAA;
|
|
1
|
+
{"version":3,"file":"rateLimit.mjs","sources":["../../../server/src/middlewares/rateLimit.js"],"sourcesContent":["'use strict';\n\nconst path = require('path');\nconst utils = require('@strapi/utils');\nconst { isString, has, toLower } = require('lodash/fp');\n\nconst { RateLimitError } = utils.errors;\n\n/**\n * Routes where the rate-limit key MUST NOT include a user identifier\n * derived from `ctx.request.body.email`.\n *\n * On these routes the request body either has no `email` field\n * (e.g. /auth/local uses `identifier`, /auth/reset-password uses\n * `code`, /auth/change-password uses `currentPassword`) or the\n * field is not part of the route contract. Including the\n * attacker-controlled `body.email` in the rate-limit key on these\n * routes lets a caller obtain a fresh key on every request by\n * varying that field, effectively bypassing per-IP throttling.\n *\n * Comparison uses endsWith so the check is stable under any router\n * mount prefix (e.g. `/api/auth/local`).\n *\n * @see https://github.com/strapi/strapi/security/advisories/GHSA-7mqx-wwh4-f9fw\n *\n * When adding a new `rateLimit`-protected auth route whose body does not\n * use `email` as the real identifier, add its path suffix here (or an\n * equivalent `routeUsesEmailIdentifier` rule) so the key cannot be split\n * with arbitrary `body.email` values.\n */\nconst ROUTES_WITHOUT_IDENTIFIER = ['/auth/local', '/auth/reset-password', '/auth/change-password'];\n\nconst isOAuthCallbackPath = (requestPath) => requestPath.includes('/connect/');\n\nconst routeUsesEmailIdentifier = (requestPath) => {\n if (isOAuthCallbackPath(requestPath)) {\n return false;\n }\n\n return !ROUTES_WITHOUT_IDENTIFIER.some((route) => requestPath.endsWith(route));\n};\n\n/**\n * Paths suitable for route matching and prefix keys: POSIX-normalized,\n * lower-cased, trailing slashes removed so `/api/auth/local` and\n * `/api/auth/local/` share one bucket.\n */\nconst normalizeRequestPathForRateLimit = (requestPath) => {\n const normalized = path.posix.normalize(requestPath);\n const lower = toLower(normalized);\n return lower.replace(/\\/+$/, '') || '/';\n};\n\nconst getEmailIdentifierForKey = (body) => {\n if (!body || !isString(body.email) || body.email === '') {\n return 'unknownIdentifier';\n }\n\n return toLower(body.email);\n};\n\nconst buildPrefixKey = (ctx) => {\n let requestPath;\n if (!isString(ctx.request.path)) {\n requestPath = 'invalidPath';\n } else {\n requestPath = normalizeRequestPathForRateLimit(ctx.request.path);\n if (requestPath === '.' || requestPath === '..') {\n requestPath = 'invalidPath';\n }\n }\n\n if (!routeUsesEmailIdentifier(requestPath)) {\n return `noIdentifier:${requestPath}:${ctx.request.ip}`;\n }\n\n const userIdentifier = getEmailIdentifierForKey(ctx.request.body);\n return `${userIdentifier}:${requestPath}:${ctx.request.ip}`;\n};\n\nconst buildRateLimitLoadConfig = (ctx, rateLimitConfig, routeMiddlewareConfig) => {\n return {\n interval: { min: 5 },\n max: 5,\n ...rateLimitConfig,\n ...routeMiddlewareConfig,\n handler() {\n throw new RateLimitError();\n },\n prefixKey: buildPrefixKey(ctx),\n };\n};\n\nmodule.exports =\n (config, { strapi }) =>\n async (ctx, next) => {\n let rateLimitConfig = strapi.config.get('plugin::users-permissions.ratelimit');\n\n if (!rateLimitConfig) {\n rateLimitConfig = {\n enabled: true,\n };\n }\n\n if (!has('enabled', rateLimitConfig)) {\n rateLimitConfig.enabled = true;\n }\n\n if (rateLimitConfig.enabled === true) {\n const rateLimit = require('koa2-ratelimit').RateLimit;\n\n const loadConfig = buildRateLimitLoadConfig(ctx, rateLimitConfig, config);\n\n return rateLimit.middleware(loadConfig)(ctx, next);\n }\n\n return next();\n };\n\nmodule.exports.buildPrefixKey = buildPrefixKey;\nmodule.exports.ROUTES_WITHOUT_IDENTIFIER = ROUTES_WITHOUT_IDENTIFIER;\nmodule.exports.normalizeRequestPathForRateLimit = normalizeRequestPathForRateLimit;\nmodule.exports.buildRateLimitLoadConfig = buildRateLimitLoadConfig;\n"],"names":["path","require$$0","utils","require$$1","isString","has","toLower","require$$2","RateLimitError","errors","ROUTES_WITHOUT_IDENTIFIER","isOAuthCallbackPath","requestPath","includes","routeUsesEmailIdentifier","some","route","endsWith","normalizeRequestPathForRateLimit","normalized","posix","normalize","lower","replace","getEmailIdentifierForKey","body","email","buildPrefixKey","ctx","request","ip","userIdentifier","buildRateLimitLoadConfig","rateLimitConfig","routeMiddlewareConfig","interval","min","max","handler","prefixKey","rateLimitModule","exports","config","strapi","next","get","enabled","rateLimit","require$$3","RateLimit","loadConfig","middleware"],"mappings":"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"}
|
|
@@ -40,6 +40,9 @@ function requireProvidersRegistry() {
|
|
|
40
40
|
},
|
|
41
41
|
async authCallback ({ accessToken }) {
|
|
42
42
|
const { body } = await bearerGet('https://discord.com/api/users/@me', accessToken);
|
|
43
|
+
if (body.verified !== true) {
|
|
44
|
+
throw new Error('Email not verified by Discord');
|
|
45
|
+
}
|
|
43
46
|
const username = body.discriminator && body.discriminator !== '0' ? `${body.username}#${body.discriminator}` : body.username;
|
|
44
47
|
return {
|
|
45
48
|
username,
|
|
@@ -64,6 +67,9 @@ function requireProvidersRegistry() {
|
|
|
64
67
|
fields: 'name,email'
|
|
65
68
|
}
|
|
66
69
|
});
|
|
70
|
+
if (!body.email) {
|
|
71
|
+
throw new Error('Email not verified by Facebook');
|
|
72
|
+
}
|
|
67
73
|
return {
|
|
68
74
|
username: body.name,
|
|
69
75
|
email: body.email
|
|
@@ -83,6 +89,10 @@ function requireProvidersRegistry() {
|
|
|
83
89
|
},
|
|
84
90
|
async authCallback ({ accessToken }) {
|
|
85
91
|
const { body } = await fetchJson(`https://oauth2.googleapis.com/tokeninfo?access_token=${encodeURIComponent(accessToken)}`);
|
|
92
|
+
const verified = body.verified_email ?? body.email_verified;
|
|
93
|
+
if (verified !== true && verified !== 'true') {
|
|
94
|
+
throw new Error('Email not verified by Google');
|
|
95
|
+
}
|
|
86
96
|
return {
|
|
87
97
|
username: body.email.split('@')[0],
|
|
88
98
|
email: body.email
|
|
@@ -107,20 +117,28 @@ function requireProvidersRegistry() {
|
|
|
107
117
|
'user-agent': 'strapi'
|
|
108
118
|
}
|
|
109
119
|
});
|
|
120
|
+
const { body: emailBody } = await bearerGet('https://api.github.com/user/emails', accessToken, {
|
|
121
|
+
headers: {
|
|
122
|
+
'user-agent': 'strapi'
|
|
123
|
+
}
|
|
124
|
+
});
|
|
110
125
|
if (userBody.email) {
|
|
126
|
+
const verifiedPublicEmail = Array.isArray(emailBody) ? emailBody.find((entry)=>entry.email === userBody.email && entry.verified === true) : null;
|
|
127
|
+
if (!verifiedPublicEmail) {
|
|
128
|
+
throw new Error('Email not verified by GitHub');
|
|
129
|
+
}
|
|
111
130
|
return {
|
|
112
131
|
username: userBody.login,
|
|
113
132
|
email: userBody.email
|
|
114
133
|
};
|
|
115
134
|
}
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
});
|
|
135
|
+
const primaryEmail = Array.isArray(emailBody) ? emailBody.find((email)=>email.primary === true) : null;
|
|
136
|
+
if (!primaryEmail || primaryEmail.verified !== true) {
|
|
137
|
+
throw new Error('Email not verified by GitHub');
|
|
138
|
+
}
|
|
121
139
|
return {
|
|
122
140
|
username: userBody.login,
|
|
123
|
-
email:
|
|
141
|
+
email: primaryEmail.email
|
|
124
142
|
};
|
|
125
143
|
}
|
|
126
144
|
},
|
|
@@ -151,19 +169,27 @@ function requireProvidersRegistry() {
|
|
|
151
169
|
secret: '',
|
|
152
170
|
callbackUrl: `${baseURL}/twitter/callback`
|
|
153
171
|
},
|
|
154
|
-
async authCallback ({ accessToken,
|
|
172
|
+
async authCallback ({ accessToken, providers, grantResponse }) {
|
|
173
|
+
const accessSecret = grantResponse?.access_secret;
|
|
174
|
+
const screenName = grantResponse?.raw?.screen_name;
|
|
175
|
+
if (!accessSecret) {
|
|
176
|
+
throw new Error('Twitter authentication requires a completed OAuth session');
|
|
177
|
+
}
|
|
155
178
|
const { twitterGet } = oauth1.__require();
|
|
156
179
|
const { body } = await twitterGet({
|
|
157
180
|
url: 'https://api.twitter.com/1.1/account/verify_credentials.json',
|
|
158
181
|
accessToken,
|
|
159
|
-
accessCredential:
|
|
182
|
+
accessCredential: accessSecret,
|
|
160
183
|
consumerKey: providers.twitter.key,
|
|
161
184
|
clientCredential: providers.twitter.secret,
|
|
162
185
|
qs: {
|
|
163
186
|
include_email: 'true',
|
|
164
|
-
screen_name:
|
|
187
|
+
screen_name: screenName
|
|
165
188
|
}
|
|
166
189
|
});
|
|
190
|
+
if (!body.email) {
|
|
191
|
+
throw new Error('Email not verified by Twitter');
|
|
192
|
+
}
|
|
167
193
|
return {
|
|
168
194
|
username: body.screen_name,
|
|
169
195
|
email: body.email
|
|
@@ -204,16 +230,24 @@ function requireProvidersRegistry() {
|
|
|
204
230
|
'email'
|
|
205
231
|
]
|
|
206
232
|
},
|
|
207
|
-
async authCallback ({ accessToken,
|
|
233
|
+
async authCallback ({ accessToken, grantResponse }) {
|
|
234
|
+
const email = grantResponse?.raw?.email;
|
|
235
|
+
const userId = grantResponse?.raw?.user_id;
|
|
236
|
+
if (!email || !userId) {
|
|
237
|
+
throw new Error('VK authentication requires a completed OAuth session');
|
|
238
|
+
}
|
|
208
239
|
const { body } = await bearerGet('https://api.vk.com/method/users.get', accessToken, {
|
|
209
240
|
qs: {
|
|
210
|
-
user_ids:
|
|
241
|
+
user_ids: userId,
|
|
211
242
|
v: '5.122'
|
|
212
243
|
}
|
|
213
244
|
});
|
|
245
|
+
if (!body.response?.[0]) {
|
|
246
|
+
throw new Error('Invalid VK access token');
|
|
247
|
+
}
|
|
214
248
|
return {
|
|
215
249
|
username: `${body.response[0].last_name} ${body.response[0].first_name}`,
|
|
216
|
-
email
|
|
250
|
+
email
|
|
217
251
|
};
|
|
218
252
|
}
|
|
219
253
|
},
|
|
@@ -234,9 +268,13 @@ function requireProvidersRegistry() {
|
|
|
234
268
|
'Client-Id': providers.twitch.key
|
|
235
269
|
}
|
|
236
270
|
});
|
|
271
|
+
const email = body.data?.[0]?.email;
|
|
272
|
+
if (!email) {
|
|
273
|
+
throw new Error('Email not verified by Twitch');
|
|
274
|
+
}
|
|
237
275
|
return {
|
|
238
276
|
username: body.data[0].login,
|
|
239
|
-
email
|
|
277
|
+
email
|
|
240
278
|
};
|
|
241
279
|
}
|
|
242
280
|
},
|
|
@@ -255,7 +293,10 @@ function requireProvidersRegistry() {
|
|
|
255
293
|
async authCallback ({ accessToken }) {
|
|
256
294
|
const { body: profileBody } = await bearerGet('https://api.linkedin.com/v2/me', accessToken);
|
|
257
295
|
const { body: emailBody } = await bearerGet('https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))', accessToken);
|
|
258
|
-
const email = emailBody.elements[0]['handle~'];
|
|
296
|
+
const email = emailBody.elements[0]?.['handle~'];
|
|
297
|
+
if (!email?.emailAddress) {
|
|
298
|
+
throw new Error('Email not verified by LinkedIn');
|
|
299
|
+
}
|
|
259
300
|
return {
|
|
260
301
|
username: profileBody.localizedFirstName,
|
|
261
302
|
email: email.emailAddress
|
|
@@ -276,13 +317,19 @@ function requireProvidersRegistry() {
|
|
|
276
317
|
'profile'
|
|
277
318
|
]
|
|
278
319
|
},
|
|
279
|
-
async authCallback ({
|
|
320
|
+
async authCallback ({ providers, grantResponse }) {
|
|
280
321
|
const jwksUrl = new URL(providers.cognito.jwksurl);
|
|
281
|
-
const idToken =
|
|
322
|
+
const idToken = grantResponse?.id_token;
|
|
323
|
+
if (!idToken) {
|
|
324
|
+
throw new Error('Cognito authentication requires a completed OAuth session');
|
|
325
|
+
}
|
|
282
326
|
const tokenPayload = await verifyJwtWithJwks$1({
|
|
283
327
|
idToken,
|
|
284
328
|
jwksUrl
|
|
285
329
|
});
|
|
330
|
+
if (tokenPayload.email_verified !== true) {
|
|
331
|
+
throw new Error('Email not verified by Cognito');
|
|
332
|
+
}
|
|
286
333
|
return {
|
|
287
334
|
username: tokenPayload['cognito:username'],
|
|
288
335
|
email: tokenPayload.email
|
|
@@ -328,6 +375,9 @@ function requireProvidersRegistry() {
|
|
|
328
375
|
},
|
|
329
376
|
async authCallback ({ accessToken, providers }) {
|
|
330
377
|
const { body } = await bearerGet(`https://${providers.auth0.subdomain}.auth0.com/userinfo`, accessToken);
|
|
378
|
+
if (body.email && body.email_verified !== true) {
|
|
379
|
+
throw new Error('Email not verified by Auth0');
|
|
380
|
+
}
|
|
331
381
|
const username = body.username || body.nickname || body.name || body.email.split('@')[0];
|
|
332
382
|
const email = body.email || `${username.replace(/\s+/g, '.')}@strapi.io`;
|
|
333
383
|
return {
|
|
@@ -352,9 +402,13 @@ function requireProvidersRegistry() {
|
|
|
352
402
|
const { body } = await bearerGet(`https://${providers.cas.subdomain}/oidc/profile`, accessToken);
|
|
353
403
|
const username = body.attributes ? body.attributes.strapiusername || body.id || body.sub : body.strapiusername || body.id || body.sub;
|
|
354
404
|
const email = body.attributes ? body.attributes.strapiemail || body.attributes.email : body.strapiemail || body.email;
|
|
405
|
+
const emailVerified = body.email_verified ?? body.attributes?.email_verified;
|
|
355
406
|
if (!username || !email) {
|
|
356
407
|
strapi.log.warn(`CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`);
|
|
357
408
|
}
|
|
409
|
+
if (email && emailVerified !== true) {
|
|
410
|
+
throw new Error('Email not verified by CAS');
|
|
411
|
+
}
|
|
358
412
|
return {
|
|
359
413
|
username,
|
|
360
414
|
email
|
|
@@ -374,8 +428,11 @@ function requireProvidersRegistry() {
|
|
|
374
428
|
]
|
|
375
429
|
},
|
|
376
430
|
async authCallback ({ accessToken }) {
|
|
377
|
-
const { body } = await bearerGet('https://www.patreon.com/api/oauth2/v2/identity?fields[user]=full_name,email', accessToken);
|
|
431
|
+
const { body } = await bearerGet('https://www.patreon.com/api/oauth2/v2/identity?fields[user]=full_name,email,is_email_verified', accessToken);
|
|
378
432
|
const patreonData = body.data.attributes;
|
|
433
|
+
if (patreonData.is_email_verified !== true) {
|
|
434
|
+
throw new Error('Email not verified by Patreon');
|
|
435
|
+
}
|
|
379
436
|
return {
|
|
380
437
|
username: patreonData.full_name,
|
|
381
438
|
email: patreonData.email
|
|
@@ -398,6 +455,9 @@ function requireProvidersRegistry() {
|
|
|
398
455
|
},
|
|
399
456
|
async authCallback ({ accessToken, providers }) {
|
|
400
457
|
const { body } = await bearerGet(`https://${providers.keycloak.subdomain}/protocol/openid-connect/userinfo`, accessToken);
|
|
458
|
+
if (body.email_verified !== true) {
|
|
459
|
+
throw new Error('Email not verified by Keycloak');
|
|
460
|
+
}
|
|
401
461
|
return {
|
|
402
462
|
username: body.preferred_username,
|
|
403
463
|
email: body.email
|
|
@@ -424,13 +484,14 @@ function requireProvidersRegistry() {
|
|
|
424
484
|
remove (name) {
|
|
425
485
|
delete authProviders[name];
|
|
426
486
|
},
|
|
427
|
-
async run ({ provider, accessToken, query, providers }) {
|
|
487
|
+
async run ({ provider, accessToken, query, providers, grantResponse }) {
|
|
428
488
|
const authProvider = authProviders[provider];
|
|
429
489
|
assert(authProvider, 'Unknown auth provider');
|
|
430
490
|
return authProvider.authCallback({
|
|
431
491
|
accessToken,
|
|
432
492
|
query,
|
|
433
|
-
providers
|
|
493
|
+
providers,
|
|
494
|
+
grantResponse
|
|
434
495
|
});
|
|
435
496
|
}
|
|
436
497
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers-registry.js","sources":["../../../server/src/services/providers-registry.js"],"sourcesContent":["'use strict';\n\nconst { strict: assert } = require('assert');\nconst urljoin = require('url-join');\n\nconst { verifyJwtWithJwks } = require('../utils/verify-jwt-with-jwks');\nconst { bearerGet, fetchJson } = require('../utils/provider-http');\n\nconst initProviders = ({ baseURL }) => ({\n email: {\n enabled: true,\n icon: 'envelope',\n grantConfig: {},\n },\n discord: {\n enabled: false,\n icon: 'discord',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/discord/callback`,\n scope: ['identify', 'email'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://discord.com/api/users/@me', accessToken);\n const username =\n body.discriminator && body.discriminator !== '0'\n ? `${body.username}#${body.discriminator}`\n : body.username;\n return {\n username,\n email: body.email,\n };\n },\n },\n facebook: {\n enabled: false,\n icon: 'facebook-square',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/facebook/callback`,\n scope: ['email'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://graph.facebook.com/me', accessToken, {\n qs: { fields: 'name,email' },\n });\n return {\n username: body.name,\n email: body.email,\n };\n },\n },\n google: {\n enabled: false,\n icon: 'google',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/google/callback`,\n scope: ['email'],\n },\n async authCallback({ accessToken }) {\n const { body } = await fetchJson(\n `https://oauth2.googleapis.com/tokeninfo?access_token=${encodeURIComponent(accessToken)}`\n );\n return {\n username: body.email.split('@')[0],\n email: body.email,\n };\n },\n },\n github: {\n enabled: false,\n icon: 'github',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/github/callback`,\n scope: ['user', 'user:email'],\n },\n async authCallback({ accessToken }) {\n const { body: userBody } = await bearerGet('https://api.github.com/user', accessToken, {\n headers: { 'user-agent': 'strapi' },\n });\n\n if (userBody.email) {\n return {\n username: userBody.login,\n email: userBody.email,\n };\n }\n\n const { body: emailBody } = await bearerGet(\n 'https://api.github.com/user/emails',\n accessToken,\n {\n headers: { 'user-agent': 'strapi' },\n }\n );\n\n return {\n username: userBody.login,\n email: Array.isArray(emailBody)\n ? emailBody.find((email) => email.primary === true).email\n : null,\n };\n },\n },\n microsoft: {\n enabled: false,\n icon: 'windows',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/microsoft/callback`,\n scope: ['user.read'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://graph.microsoft.com/v1.0/me', accessToken);\n return {\n username: body.userPrincipalName,\n email: body.userPrincipalName,\n };\n },\n },\n\n twitter: {\n enabled: false,\n icon: 'twitter',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/twitter/callback`,\n },\n async authCallback({ accessToken, query, providers }) {\n const { twitterGet } = require('../utils/oauth-connect/oauth1');\n const { body } = await twitterGet({\n url: 'https://api.twitter.com/1.1/account/verify_credentials.json',\n accessToken,\n accessCredential: query.access_secret,\n consumerKey: providers.twitter.key,\n clientCredential: providers.twitter.secret,\n qs: { include_email: 'true', screen_name: query['raw[screen_name]'] },\n });\n\n return {\n username: body.screen_name,\n email: body.email,\n };\n },\n },\n instagram: {\n enabled: false,\n icon: 'instagram',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/instagram/callback`,\n scope: ['user_profile'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://graph.instagram.com/me', accessToken, {\n qs: { fields: 'id,username' },\n });\n return {\n username: body.username,\n email: `${body.username}@strapi.io`,\n };\n },\n },\n vk: {\n enabled: false,\n icon: 'vk',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/vk/callback`,\n scope: ['email'],\n },\n async authCallback({ accessToken, query }) {\n const { body } = await bearerGet('https://api.vk.com/method/users.get', accessToken, {\n qs: { user_ids: query.raw.user_id, v: '5.122' },\n });\n return {\n username: `${body.response[0].last_name} ${body.response[0].first_name}`,\n email: query.raw.email,\n };\n },\n },\n\n twitch: {\n enabled: false,\n icon: 'twitch',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/twitch/callback`,\n scope: ['user:read:email'],\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet('https://api.twitch.tv/helix/users', accessToken, {\n headers: {\n 'Client-Id': providers.twitch.key,\n },\n });\n return {\n username: body.data[0].login,\n email: body.data[0].email,\n };\n },\n },\n\n linkedin: {\n enabled: false,\n icon: 'linkedin',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/linkedin/callback`,\n scope: ['r_liteprofile', 'r_emailaddress'],\n },\n async authCallback({ accessToken }) {\n const { body: profileBody } = await bearerGet('https://api.linkedin.com/v2/me', accessToken);\n const { body: emailBody } = await bearerGet(\n 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))',\n accessToken\n );\n\n const email = emailBody.elements[0]['handle~'];\n\n return {\n username: profileBody.localizedFirstName,\n email: email.emailAddress,\n };\n },\n },\n\n cognito: {\n enabled: false,\n icon: 'aws',\n grantConfig: {\n key: '',\n secret: '',\n subdomain: 'my.subdomain.com',\n callback: `${baseURL}/cognito/callback`,\n scope: ['email', 'openid', 'profile'],\n },\n async authCallback({ query, providers }) {\n const jwksUrl = new URL(providers.cognito.jwksurl);\n const idToken = query.id_token;\n const tokenPayload = await verifyJwtWithJwks({ idToken, jwksUrl });\n return {\n username: tokenPayload['cognito:username'],\n email: tokenPayload.email,\n };\n },\n },\n\n reddit: {\n enabled: false,\n icon: 'reddit',\n grantConfig: {\n key: '',\n secret: '',\n callback: `${baseURL}/reddit/callback`,\n scope: ['identity'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://oauth.reddit.com/api/v1/me', accessToken, {\n headers: { 'user-agent': 'strapi' },\n });\n return {\n username: body.name,\n email: `${body.name}@strapi.io`,\n };\n },\n },\n\n auth0: {\n enabled: false,\n icon: '',\n grantConfig: {\n key: '',\n secret: '',\n subdomain: 'my-tenant.eu',\n callback: `${baseURL}/auth0/callback`,\n scope: ['openid', 'email', 'profile'],\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet(\n `https://${providers.auth0.subdomain}.auth0.com/userinfo`,\n accessToken\n );\n const username = body.username || body.nickname || body.name || body.email.split('@')[0];\n const email = body.email || `${username.replace(/\\s+/g, '.')}@strapi.io`;\n\n return {\n username,\n email,\n };\n },\n },\n\n cas: {\n enabled: false,\n icon: 'book',\n grantConfig: {\n key: '',\n secret: '',\n callback: `${baseURL}/cas/callback`,\n scope: ['openid email'],\n subdomain: 'my.subdomain.com/cas',\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet(\n `https://${providers.cas.subdomain}/oidc/profile`,\n accessToken\n );\n const username = body.attributes\n ? body.attributes.strapiusername || body.id || body.sub\n : body.strapiusername || body.id || body.sub;\n const email = body.attributes\n ? body.attributes.strapiemail || body.attributes.email\n : body.strapiemail || body.email;\n if (!username || !email) {\n strapi.log.warn(\n `CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`\n );\n }\n return {\n username,\n email,\n };\n },\n },\n\n patreon: {\n enabled: false,\n icon: '',\n grantConfig: {\n key: '',\n secret: '',\n callback: `${baseURL}/patreon/callback`,\n scope: ['identity', 'identity[email]'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet(\n 'https://www.patreon.com/api/oauth2/v2/identity?fields[user]=full_name,email',\n accessToken\n );\n const patreonData = body.data.attributes;\n return {\n username: patreonData.full_name,\n email: patreonData.email,\n };\n },\n },\n keycloak: {\n enabled: false,\n icon: '',\n grantConfig: {\n key: '',\n secret: '',\n subdomain: 'myKeycloakProvider.com/realms/myrealm',\n callback: `${baseURL}/keycloak/callback`,\n scope: ['openid', 'email', 'profile'],\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet(\n `https://${providers.keycloak.subdomain}/protocol/openid-connect/userinfo`,\n accessToken\n );\n return {\n username: body.preferred_username,\n email: body.email,\n };\n },\n },\n});\n\nmodule.exports = () => {\n const apiPrefix = strapi.config.get('api.rest.prefix');\n const baseURL = urljoin(strapi.config.server.url, apiPrefix, 'auth');\n\n const authProviders = initProviders({ baseURL });\n\n return {\n getAll() {\n return authProviders;\n },\n get(name) {\n return authProviders[name];\n },\n add(name, config) {\n authProviders[name] = config;\n },\n remove(name) {\n delete authProviders[name];\n },\n\n async run({ provider, accessToken, query, providers }) {\n const authProvider = authProviders[provider];\n\n assert(authProvider, 'Unknown auth provider');\n\n return authProvider.authCallback({ accessToken, query, providers });\n },\n };\n};\n"],"names":["strict","assert","require$$0","urljoin","require$$1","verifyJwtWithJwks","require$$2","bearerGet","fetchJson","require$$3","initProviders","baseURL","email","enabled","icon","grantConfig","discord","key","secret","callbackUrl","scope","authCallback","accessToken","body","username","discriminator","facebook","qs","fields","name","google","encodeURIComponent","split","github","userBody","headers","login","emailBody","Array","isArray","find","primary","microsoft","userPrincipalName","twitter","query","providers","twitterGet","require$$4","url","accessCredential","access_secret","consumerKey","clientCredential","include_email","screen_name","instagram","vk","user_ids","raw","user_id","v","response","last_name","first_name","twitch","data","linkedin","profileBody","elements","localizedFirstName","emailAddress","cognito","subdomain","callback","jwksUrl","URL","jwksurl","idToken","id_token","tokenPayload","reddit","auth0","nickname","replace","cas","attributes","strapiusername","id","sub","strapiemail","strapi","log","warn","JSON","stringify","patreon","patreonData","full_name","keycloak","preferred_username","providersRegistry","apiPrefix","config","get","server","authProviders","getAll","add","remove","run","provider","authProvider"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"providers-registry.js","sources":["../../../server/src/services/providers-registry.js"],"sourcesContent":["'use strict';\n\nconst { strict: assert } = require('assert');\nconst urljoin = require('url-join');\n\nconst { verifyJwtWithJwks } = require('../utils/verify-jwt-with-jwks');\nconst { bearerGet, fetchJson } = require('../utils/provider-http');\n\nconst initProviders = ({ baseURL }) => ({\n email: {\n enabled: true,\n icon: 'envelope',\n grantConfig: {},\n },\n discord: {\n enabled: false,\n icon: 'discord',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/discord/callback`,\n scope: ['identify', 'email'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://discord.com/api/users/@me', accessToken);\n if (body.verified !== true) {\n throw new Error('Email not verified by Discord');\n }\n const username =\n body.discriminator && body.discriminator !== '0'\n ? `${body.username}#${body.discriminator}`\n : body.username;\n return {\n username,\n email: body.email,\n };\n },\n },\n facebook: {\n enabled: false,\n icon: 'facebook-square',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/facebook/callback`,\n scope: ['email'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://graph.facebook.com/me', accessToken, {\n qs: { fields: 'name,email' },\n });\n if (!body.email) {\n throw new Error('Email not verified by Facebook');\n }\n return {\n username: body.name,\n email: body.email,\n };\n },\n },\n google: {\n enabled: false,\n icon: 'google',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/google/callback`,\n scope: ['email'],\n },\n async authCallback({ accessToken }) {\n const { body } = await fetchJson(\n `https://oauth2.googleapis.com/tokeninfo?access_token=${encodeURIComponent(accessToken)}`\n );\n const verified = body.verified_email ?? body.email_verified;\n if (verified !== true && verified !== 'true') {\n throw new Error('Email not verified by Google');\n }\n return {\n username: body.email.split('@')[0],\n email: body.email,\n };\n },\n },\n github: {\n enabled: false,\n icon: 'github',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/github/callback`,\n scope: ['user', 'user:email'],\n },\n async authCallback({ accessToken }) {\n const { body: userBody } = await bearerGet('https://api.github.com/user', accessToken, {\n headers: { 'user-agent': 'strapi' },\n });\n\n const { body: emailBody } = await bearerGet(\n 'https://api.github.com/user/emails',\n accessToken,\n {\n headers: { 'user-agent': 'strapi' },\n }\n );\n\n if (userBody.email) {\n const verifiedPublicEmail = Array.isArray(emailBody)\n ? emailBody.find((entry) => entry.email === userBody.email && entry.verified === true)\n : null;\n\n if (!verifiedPublicEmail) {\n throw new Error('Email not verified by GitHub');\n }\n\n return {\n username: userBody.login,\n email: userBody.email,\n };\n }\n\n const primaryEmail = Array.isArray(emailBody)\n ? emailBody.find((email) => email.primary === true)\n : null;\n\n if (!primaryEmail || primaryEmail.verified !== true) {\n throw new Error('Email not verified by GitHub');\n }\n\n return {\n username: userBody.login,\n email: primaryEmail.email,\n };\n },\n },\n microsoft: {\n enabled: false,\n icon: 'windows',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/microsoft/callback`,\n scope: ['user.read'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://graph.microsoft.com/v1.0/me', accessToken);\n return {\n username: body.userPrincipalName,\n email: body.userPrincipalName,\n };\n },\n },\n\n twitter: {\n enabled: false,\n icon: 'twitter',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/twitter/callback`,\n },\n async authCallback({ accessToken, providers, grantResponse }) {\n const accessSecret = grantResponse?.access_secret;\n const screenName = grantResponse?.raw?.screen_name;\n\n if (!accessSecret) {\n throw new Error('Twitter authentication requires a completed OAuth session');\n }\n\n const { twitterGet } = require('../utils/oauth-connect/oauth1');\n const { body } = await twitterGet({\n url: 'https://api.twitter.com/1.1/account/verify_credentials.json',\n accessToken,\n accessCredential: accessSecret,\n consumerKey: providers.twitter.key,\n clientCredential: providers.twitter.secret,\n qs: { include_email: 'true', screen_name: screenName },\n });\n\n if (!body.email) {\n throw new Error('Email not verified by Twitter');\n }\n\n return {\n username: body.screen_name,\n email: body.email,\n };\n },\n },\n instagram: {\n enabled: false,\n icon: 'instagram',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/instagram/callback`,\n scope: ['user_profile'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://graph.instagram.com/me', accessToken, {\n qs: { fields: 'id,username' },\n });\n return {\n username: body.username,\n email: `${body.username}@strapi.io`,\n };\n },\n },\n vk: {\n enabled: false,\n icon: 'vk',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/vk/callback`,\n scope: ['email'],\n },\n async authCallback({ accessToken, grantResponse }) {\n const email = grantResponse?.raw?.email;\n const userId = grantResponse?.raw?.user_id;\n\n if (!email || !userId) {\n throw new Error('VK authentication requires a completed OAuth session');\n }\n\n const { body } = await bearerGet('https://api.vk.com/method/users.get', accessToken, {\n qs: { user_ids: userId, v: '5.122' },\n });\n\n if (!body.response?.[0]) {\n throw new Error('Invalid VK access token');\n }\n\n return {\n username: `${body.response[0].last_name} ${body.response[0].first_name}`,\n email,\n };\n },\n },\n\n twitch: {\n enabled: false,\n icon: 'twitch',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/twitch/callback`,\n scope: ['user:read:email'],\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet('https://api.twitch.tv/helix/users', accessToken, {\n headers: {\n 'Client-Id': providers.twitch.key,\n },\n });\n const email = body.data?.[0]?.email;\n if (!email) {\n throw new Error('Email not verified by Twitch');\n }\n return {\n username: body.data[0].login,\n email,\n };\n },\n },\n\n linkedin: {\n enabled: false,\n icon: 'linkedin',\n grantConfig: {\n key: '',\n secret: '',\n callbackUrl: `${baseURL}/linkedin/callback`,\n scope: ['r_liteprofile', 'r_emailaddress'],\n },\n async authCallback({ accessToken }) {\n const { body: profileBody } = await bearerGet('https://api.linkedin.com/v2/me', accessToken);\n const { body: emailBody } = await bearerGet(\n 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))',\n accessToken\n );\n\n const email = emailBody.elements[0]?.['handle~'];\n\n if (!email?.emailAddress) {\n throw new Error('Email not verified by LinkedIn');\n }\n\n return {\n username: profileBody.localizedFirstName,\n email: email.emailAddress,\n };\n },\n },\n\n cognito: {\n enabled: false,\n icon: 'aws',\n grantConfig: {\n key: '',\n secret: '',\n subdomain: 'my.subdomain.com',\n callback: `${baseURL}/cognito/callback`,\n scope: ['email', 'openid', 'profile'],\n },\n async authCallback({ providers, grantResponse }) {\n const jwksUrl = new URL(providers.cognito.jwksurl);\n const idToken = grantResponse?.id_token;\n\n if (!idToken) {\n throw new Error('Cognito authentication requires a completed OAuth session');\n }\n\n const tokenPayload = await verifyJwtWithJwks({ idToken, jwksUrl });\n if (tokenPayload.email_verified !== true) {\n throw new Error('Email not verified by Cognito');\n }\n return {\n username: tokenPayload['cognito:username'],\n email: tokenPayload.email,\n };\n },\n },\n\n reddit: {\n enabled: false,\n icon: 'reddit',\n grantConfig: {\n key: '',\n secret: '',\n callback: `${baseURL}/reddit/callback`,\n scope: ['identity'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet('https://oauth.reddit.com/api/v1/me', accessToken, {\n headers: { 'user-agent': 'strapi' },\n });\n return {\n username: body.name,\n email: `${body.name}@strapi.io`,\n };\n },\n },\n\n auth0: {\n enabled: false,\n icon: '',\n grantConfig: {\n key: '',\n secret: '',\n subdomain: 'my-tenant.eu',\n callback: `${baseURL}/auth0/callback`,\n scope: ['openid', 'email', 'profile'],\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet(\n `https://${providers.auth0.subdomain}.auth0.com/userinfo`,\n accessToken\n );\n if (body.email && body.email_verified !== true) {\n throw new Error('Email not verified by Auth0');\n }\n const username = body.username || body.nickname || body.name || body.email.split('@')[0];\n const email = body.email || `${username.replace(/\\s+/g, '.')}@strapi.io`;\n\n return {\n username,\n email,\n };\n },\n },\n\n cas: {\n enabled: false,\n icon: 'book',\n grantConfig: {\n key: '',\n secret: '',\n callback: `${baseURL}/cas/callback`,\n scope: ['openid email'],\n subdomain: 'my.subdomain.com/cas',\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet(\n `https://${providers.cas.subdomain}/oidc/profile`,\n accessToken\n );\n const username = body.attributes\n ? body.attributes.strapiusername || body.id || body.sub\n : body.strapiusername || body.id || body.sub;\n const email = body.attributes\n ? body.attributes.strapiemail || body.attributes.email\n : body.strapiemail || body.email;\n const emailVerified = body.email_verified ?? body.attributes?.email_verified;\n if (!username || !email) {\n strapi.log.warn(\n `CAS Response Body did not contain required attributes: ${JSON.stringify(body)}`\n );\n }\n if (email && emailVerified !== true) {\n throw new Error('Email not verified by CAS');\n }\n return {\n username,\n email,\n };\n },\n },\n\n patreon: {\n enabled: false,\n icon: '',\n grantConfig: {\n key: '',\n secret: '',\n callback: `${baseURL}/patreon/callback`,\n scope: ['identity', 'identity[email]'],\n },\n async authCallback({ accessToken }) {\n const { body } = await bearerGet(\n 'https://www.patreon.com/api/oauth2/v2/identity?fields[user]=full_name,email,is_email_verified',\n accessToken\n );\n const patreonData = body.data.attributes;\n if (patreonData.is_email_verified !== true) {\n throw new Error('Email not verified by Patreon');\n }\n return {\n username: patreonData.full_name,\n email: patreonData.email,\n };\n },\n },\n keycloak: {\n enabled: false,\n icon: '',\n grantConfig: {\n key: '',\n secret: '',\n subdomain: 'myKeycloakProvider.com/realms/myrealm',\n callback: `${baseURL}/keycloak/callback`,\n scope: ['openid', 'email', 'profile'],\n },\n async authCallback({ accessToken, providers }) {\n const { body } = await bearerGet(\n `https://${providers.keycloak.subdomain}/protocol/openid-connect/userinfo`,\n accessToken\n );\n if (body.email_verified !== true) {\n throw new Error('Email not verified by Keycloak');\n }\n return {\n username: body.preferred_username,\n email: body.email,\n };\n },\n },\n});\n\nmodule.exports = () => {\n const apiPrefix = strapi.config.get('api.rest.prefix');\n const baseURL = urljoin(strapi.config.server.url, apiPrefix, 'auth');\n\n const authProviders = initProviders({ baseURL });\n\n return {\n getAll() {\n return authProviders;\n },\n get(name) {\n return authProviders[name];\n },\n add(name, config) {\n authProviders[name] = config;\n },\n remove(name) {\n delete authProviders[name];\n },\n\n async run({ provider, accessToken, query, providers, grantResponse }) {\n const authProvider = authProviders[provider];\n\n assert(authProvider, 'Unknown auth provider');\n\n return authProvider.authCallback({ accessToken, query, providers, grantResponse });\n },\n };\n};\n"],"names":["strict","assert","require$$0","urljoin","require$$1","verifyJwtWithJwks","require$$2","bearerGet","fetchJson","require$$3","initProviders","baseURL","email","enabled","icon","grantConfig","discord","key","secret","callbackUrl","scope","authCallback","accessToken","body","verified","Error","username","discriminator","facebook","qs","fields","name","google","encodeURIComponent","verified_email","email_verified","split","github","userBody","headers","emailBody","verifiedPublicEmail","Array","isArray","find","entry","login","primaryEmail","primary","microsoft","userPrincipalName","twitter","providers","grantResponse","accessSecret","access_secret","screenName","raw","screen_name","twitterGet","require$$4","url","accessCredential","consumerKey","clientCredential","include_email","instagram","vk","userId","user_id","user_ids","v","response","last_name","first_name","twitch","data","linkedin","profileBody","elements","emailAddress","localizedFirstName","cognito","subdomain","callback","jwksUrl","URL","jwksurl","idToken","id_token","tokenPayload","reddit","auth0","nickname","replace","cas","attributes","strapiusername","id","sub","strapiemail","emailVerified","strapi","log","warn","JSON","stringify","patreon","patreonData","is_email_verified","full_name","keycloak","preferred_username","providersRegistry","apiPrefix","config","get","server","authProviders","getAll","add","remove","run","provider","query","authProvider"],"mappings":"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"}
|