@strapi/plugin-users-permissions 5.52.3 → 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 +7 -1
- package/dist/server/controllers/auth.js.map +1 -1
- package/dist/server/controllers/auth.mjs +7 -1
- 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/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 +9 -1
- 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/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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../server/src/utils/oauth-connect/index.js"],"sourcesContent":["'use strict';\n\nconst { errors } = require('@strapi/utils');\n\nconst builtinProviderEndpoints = require('./providers');\nconst oauth1 = require('./oauth1');\nconst oauth2 = require('./oauth2');\n\nconst CONNECT_PREFIX = '/connect';\n\nconst parseConnectPath = (requestPath, apiPrefix) => {\n const prefix = `${apiPrefix}${CONNECT_PREFIX}/`;\n if (!requestPath.startsWith(prefix)) {\n return null;\n }\n\n const remainder = requestPath.slice(prefix.length);\n const [provider, segment] = remainder.split('/').filter(Boolean);\n\n if (!provider) {\n return null;\n }\n\n return {\n provider,\n isCallback: segment === 'callback',\n };\n};\n\n/**\n * Resolve OAuth endpoint config from built-ins, falling back to store-defined\n * endpoints so custom providers registered via providers-registry still work.\n */\nconst buildProviderConfig = (providerName, storedConfig, redirectUri) => {\n const defaults = builtinProviderEndpoints[providerName];\n const endpoints = defaults || {\n oauth: storedConfig.oauth,\n authorize_url: storedConfig.authorize_url,\n access_url: storedConfig.access_url,\n request_url: storedConfig.request_url,\n scope_delimiter: storedConfig.scope_delimiter,\n token_endpoint_auth_method: storedConfig.token_endpoint_auth_method,\n };\n\n if (endpoints.oauth === 1) {\n if (!endpoints.request_url || !endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n } else if (!endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n\n return {\n name: providerName,\n ...endpoints,\n key: storedConfig.key,\n secret: storedConfig.secret,\n scope: storedConfig.scope,\n subdomain: storedConfig.subdomain,\n callback: storedConfig.callback,\n redirect_uri: redirectUri,\n };\n};\n\nconst redirectWithPayload = (ctx, callbackUrl, payload) => {\n const url = new URL(callbackUrl);\n const params = new URLSearchParams();\n\n Object.entries(payload).forEach(([key, value]) => {\n if (key === 'raw') {\n Object.entries(value).forEach(([rawKey, rawValue]) => {\n params.set(`raw[${rawKey}]`, String(rawValue));\n });\n return;\n }\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n });\n\n url.search = params.toString();\n ctx.redirect(url.toString());\n};\n\nconst preserveGrantDynamic = (ctx) => {\n const dynamic = ctx.session.grant?.dynamic;\n return dynamic ? { dynamic } : {};\n};\n\nconst startOAuth1Flow = async (ctx, provider, parsed, redirectUri) => {\n const requestToken = await oauth1.requestToken({\n requestUrl: provider.request_url,\n redirectUri,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n });\n\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n request: requestToken,\n };\n\n const authorizeUrl = `${provider.authorize_url}?oauth_token=${encodeURIComponent(requestToken.oauth_token)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst startOAuth2Flow = (ctx, provider, parsed, redirectUri) => {\n const state = oauth2.generateState();\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n state,\n };\n\n let authorizeUrl = oauth2.buildAuthorizeUrl(provider, {\n key: provider.key,\n redirectUri,\n scope: provider.scope,\n subdomain: provider.subdomain,\n });\n\n authorizeUrl += `&state=${encodeURIComponent(state)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst handleOAuth1Callback = async (ctx, provider, callbackUrl) => {\n const session = ctx.session.grant || {};\n const { oauth_token: oauthToken, oauth_verifier: oauthVerifier } = ctx.query;\n const requestToken = session.request;\n\n if (!requestToken?.oauth_token || oauthToken !== requestToken.oauth_token) {\n throw new Error('OAuth1 token mismatch');\n }\n\n const tokenResponse = await oauth1.accessToken({\n accessUrl: provider.access_url,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n oauthToken,\n oauthVerifier,\n oauthTokenCredential: requestToken.oauth_token_secret,\n });\n\n const payload = oauth2.tokensToQueryPayload(provider, tokenResponse);\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, payload);\n};\n\nconst handleOAuth2Callback = async (ctx, provider, callbackUrl, redirectUri) => {\n const session = ctx.session.grant || {};\n const { code, state: queryState, error, error_description: errorDescription } = ctx.query;\n\n if (error) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error,\n error_description: errorDescription,\n });\n }\n\n if (!code) {\n throw new Error('OAuth2 missing code parameter');\n }\n\n // Reject when session state is missing (not only on mismatch) to close login-CSRF.\n if (!session.state || queryState !== session.state) {\n throw new Error('OAuth2 state mismatch');\n }\n\n const tokenResponse = await oauth2.exchangeAuthorizationCode(provider, {\n key: provider.key,\n secret: provider.secret,\n redirectUri,\n code,\n subdomain: provider.subdomain,\n });\n\n const payload = oauth2.tokensToQueryPayload(provider, tokenResponse);\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, payload);\n};\n\nconst createOAuthConnectMiddleware = () => {\n return async (ctx, next) => {\n const apiPrefix = strapi.config.get('api.rest.prefix');\n const [requestPath] = ctx.request.url.split('?');\n const parsed = parseConnectPath(requestPath, apiPrefix);\n\n if (!parsed) {\n return next();\n }\n\n if (!ctx.session) {\n ctx.throw(400, 'OAuth connect requires session middleware');\n }\n\n const storedProviders = await strapi\n .store({ type: 'plugin', name: 'users-permissions', key: 'grant' })\n .get();\n\n const storedConfig = storedProviders?.[parsed.provider];\n if (!storedConfig?.enabled) {\n throw new errors.ApplicationError('This provider is disabled');\n }\n\n const { getService } = require('..');\n const redirectUri = getService('providers').buildRedirectUri(parsed.provider);\n\n const callbackOverride =\n ctx.state.oauthConnect?.callback ?? ctx.session.grant?.dynamic?.callback;\n const effectiveConfig = callbackOverride\n ? { ...storedConfig, callback: callbackOverride }\n : storedConfig;\n\n const provider = buildProviderConfig(parsed.provider, effectiveConfig, redirectUri);\n\n if (!provider) {\n throw new errors.ApplicationError('Unknown OAuth provider');\n }\n\n ctx.session.grant = ctx.session.grant || {};\n\n if (!parsed.isCallback) {\n if (provider.oauth === 1) {\n return startOAuth1Flow(ctx, provider, parsed, redirectUri);\n }\n return startOAuth2Flow(ctx, provider, parsed, redirectUri);\n }\n\n const callbackUrl = effectiveConfig.callback;\n if (!callbackUrl) {\n throw new errors.ApplicationError('Provider callback URL is not configured');\n }\n\n try {\n if (provider.oauth === 1) {\n return await handleOAuth1Callback(ctx, provider, callbackUrl);\n }\n return await handleOAuth2Callback(ctx, provider, callbackUrl, redirectUri);\n } catch (err) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error: 'oauth_error',\n error_description: err.message,\n });\n }\n };\n};\n\nmodule.exports = {\n createOAuthConnectMiddleware,\n parseConnectPath,\n buildProviderConfig,\n redirectWithPayload,\n};\n"],"names":["errors","require$$0","builtinProviderEndpoints","require$$1","oauth1","require$$2","oauth2","require$$3","CONNECT_PREFIX","parseConnectPath","requestPath","apiPrefix","prefix","startsWith","remainder","slice","length","provider","segment","split","filter","Boolean","isCallback","buildProviderConfig","providerName","storedConfig","redirectUri","defaults","endpoints","oauth","authorize_url","access_url","request_url","scope_delimiter","token_endpoint_auth_method","name","key","secret","scope","subdomain","callback","redirect_uri","redirectWithPayload","ctx","callbackUrl","payload","url","URL","params","URLSearchParams","Object","entries","forEach","value","rawKey","rawValue","set","String","undefined","search","toString","redirect","preserveGrantDynamic","dynamic","session","grant","startOAuth1Flow","parsed","requestToken","requestUrl","consumerKey","clientCredential","request","authorizeUrl","encodeURIComponent","oauth_token","startOAuth2Flow","state","generateState","buildAuthorizeUrl","handleOAuth1Callback","oauthToken","oauth_verifier","oauthVerifier","query","Error","tokenResponse","accessToken","accessUrl","oauthTokenCredential","oauth_token_secret","tokensToQueryPayload","handleOAuth2Callback","code","queryState","error","error_description","errorDescription","exchangeAuthorizationCode","createOAuthConnectMiddleware","next","strapi","config","get","throw","storedProviders","store","type","enabled","ApplicationError","getService","require$$4","buildRedirectUri","callbackOverride","oauthConnect","effectiveConfig","err","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../server/src/utils/oauth-connect/index.js"],"sourcesContent":["'use strict';\n\nconst { errors } = require('@strapi/utils');\n\nconst builtinProviderEndpoints = require('./providers');\nconst oauth1 = require('./oauth1');\nconst oauth2 = require('./oauth2');\nconst { trimGrantSessionResponse } = require('../trim-grant-session-response');\n\nconst CONNECT_PREFIX = '/connect';\n\nconst parseConnectPath = (requestPath, apiPrefix) => {\n const prefix = `${apiPrefix}${CONNECT_PREFIX}/`;\n if (!requestPath.startsWith(prefix)) {\n return null;\n }\n\n const remainder = requestPath.slice(prefix.length);\n const [provider, segment] = remainder.split('/').filter(Boolean);\n\n if (!provider) {\n return null;\n }\n\n return {\n provider,\n isCallback: segment === 'callback',\n };\n};\n\n/**\n * Resolve OAuth endpoint config from built-ins, falling back to store-defined\n * endpoints so custom providers registered via providers-registry still work.\n */\nconst buildProviderConfig = (providerName, storedConfig, redirectUri) => {\n const defaults = builtinProviderEndpoints[providerName];\n const endpoints = defaults || {\n oauth: storedConfig.oauth,\n authorize_url: storedConfig.authorize_url,\n access_url: storedConfig.access_url,\n request_url: storedConfig.request_url,\n scope_delimiter: storedConfig.scope_delimiter,\n token_endpoint_auth_method: storedConfig.token_endpoint_auth_method,\n };\n\n if (endpoints.oauth === 1) {\n if (!endpoints.request_url || !endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n } else if (!endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n\n return {\n name: providerName,\n ...endpoints,\n key: storedConfig.key,\n secret: storedConfig.secret,\n scope: storedConfig.scope,\n subdomain: storedConfig.subdomain,\n callback: storedConfig.callback,\n redirect_uri: redirectUri,\n };\n};\n\nconst redirectWithPayload = (ctx, callbackUrl, payload) => {\n const url = new URL(callbackUrl);\n const params = new URLSearchParams();\n\n Object.entries(payload).forEach(([key, value]) => {\n if (key === 'raw') {\n Object.entries(value).forEach(([rawKey, rawValue]) => {\n params.set(`raw[${rawKey}]`, String(rawValue));\n });\n return;\n }\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n });\n\n url.search = params.toString();\n ctx.redirect(url.toString());\n};\n\nconst preserveGrantDynamic = (ctx) => {\n const dynamic = ctx.session.grant?.dynamic;\n return dynamic ? { dynamic } : {};\n};\n\nconst redirectWithSessionResponse = (ctx, callbackUrl, provider, tokenResponse) => {\n const grantResponse = oauth2.tokensToQueryPayload(provider, tokenResponse);\n ctx.session.grant = {\n response: trimGrantSessionResponse(grantResponse, provider.name),\n };\n\n return redirectWithPayload(ctx, callbackUrl, {});\n};\n\nconst startOAuth1Flow = async (ctx, provider, parsed, redirectUri) => {\n const requestToken = await oauth1.requestToken({\n requestUrl: provider.request_url,\n redirectUri,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n });\n\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n request: requestToken,\n };\n\n const authorizeUrl = `${provider.authorize_url}?oauth_token=${encodeURIComponent(requestToken.oauth_token)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst startOAuth2Flow = (ctx, provider, parsed, redirectUri) => {\n const state = oauth2.generateState();\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n state,\n };\n\n let authorizeUrl = oauth2.buildAuthorizeUrl(provider, {\n key: provider.key,\n redirectUri,\n scope: provider.scope,\n subdomain: provider.subdomain,\n });\n\n authorizeUrl += `&state=${encodeURIComponent(state)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst handleOAuth1Callback = async (ctx, provider, callbackUrl) => {\n const session = ctx.session.grant || {};\n const { oauth_token: oauthToken, oauth_verifier: oauthVerifier } = ctx.query;\n const requestToken = session.request;\n\n if (!requestToken?.oauth_token || oauthToken !== requestToken.oauth_token) {\n throw new Error('OAuth1 token mismatch');\n }\n\n const tokenResponse = await oauth1.accessToken({\n accessUrl: provider.access_url,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n oauthToken,\n oauthVerifier,\n oauthTokenCredential: requestToken.oauth_token_secret,\n });\n\n return redirectWithSessionResponse(ctx, callbackUrl, provider, tokenResponse);\n};\n\nconst handleOAuth2Callback = async (ctx, provider, callbackUrl, redirectUri) => {\n const session = ctx.session.grant || {};\n const { code, state: queryState, error, error_description: errorDescription } = ctx.query;\n\n if (error) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error,\n error_description: errorDescription,\n });\n }\n\n if (!code) {\n throw new Error('OAuth2 missing code parameter');\n }\n\n // Reject when session state is missing (not only on mismatch) to close login-CSRF.\n if (!session.state || queryState !== session.state) {\n throw new Error('OAuth2 state mismatch');\n }\n\n const tokenResponse = await oauth2.exchangeAuthorizationCode(provider, {\n key: provider.key,\n secret: provider.secret,\n redirectUri,\n code,\n subdomain: provider.subdomain,\n });\n\n return redirectWithSessionResponse(ctx, callbackUrl, provider, tokenResponse);\n};\n\nconst createOAuthConnectMiddleware = () => {\n return async (ctx, next) => {\n const apiPrefix = strapi.config.get('api.rest.prefix');\n const [requestPath] = ctx.request.url.split('?');\n const parsed = parseConnectPath(requestPath, apiPrefix);\n\n if (!parsed) {\n return next();\n }\n\n if (!ctx.session) {\n ctx.throw(400, 'OAuth connect requires session middleware');\n }\n\n const storedProviders = await strapi\n .store({ type: 'plugin', name: 'users-permissions', key: 'grant' })\n .get();\n\n const storedConfig = storedProviders?.[parsed.provider];\n if (!storedConfig?.enabled) {\n throw new errors.ApplicationError('This provider is disabled');\n }\n\n const { getService } = require('..');\n const redirectUri = getService('providers').buildRedirectUri(parsed.provider);\n\n const callbackOverride =\n ctx.state.oauthConnect?.callback ?? ctx.session.grant?.dynamic?.callback;\n const effectiveConfig = callbackOverride\n ? { ...storedConfig, callback: callbackOverride }\n : storedConfig;\n\n const provider = buildProviderConfig(parsed.provider, effectiveConfig, redirectUri);\n\n if (!provider) {\n throw new errors.ApplicationError('Unknown OAuth provider');\n }\n\n ctx.session.grant = ctx.session.grant || {};\n\n if (!parsed.isCallback) {\n if (provider.oauth === 1) {\n return startOAuth1Flow(ctx, provider, parsed, redirectUri);\n }\n return startOAuth2Flow(ctx, provider, parsed, redirectUri);\n }\n\n const callbackUrl = effectiveConfig.callback;\n if (!callbackUrl) {\n throw new errors.ApplicationError('Provider callback URL is not configured');\n }\n\n try {\n if (provider.oauth === 1) {\n return await handleOAuth1Callback(ctx, provider, callbackUrl);\n }\n return await handleOAuth2Callback(ctx, provider, callbackUrl, redirectUri);\n } catch (err) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error: 'oauth_error',\n error_description: err.message,\n });\n }\n };\n};\n\nmodule.exports = {\n createOAuthConnectMiddleware,\n parseConnectPath,\n buildProviderConfig,\n redirectWithPayload,\n};\n"],"names":["errors","require$$0","builtinProviderEndpoints","require$$1","oauth1","require$$2","oauth2","require$$3","trimGrantSessionResponse","require$$4","CONNECT_PREFIX","parseConnectPath","requestPath","apiPrefix","prefix","startsWith","remainder","slice","length","provider","segment","split","filter","Boolean","isCallback","buildProviderConfig","providerName","storedConfig","redirectUri","defaults","endpoints","oauth","authorize_url","access_url","request_url","scope_delimiter","token_endpoint_auth_method","name","key","secret","scope","subdomain","callback","redirect_uri","redirectWithPayload","ctx","callbackUrl","payload","url","URL","params","URLSearchParams","Object","entries","forEach","value","rawKey","rawValue","set","String","undefined","search","toString","redirect","preserveGrantDynamic","dynamic","session","grant","redirectWithSessionResponse","tokenResponse","grantResponse","tokensToQueryPayload","response","startOAuth1Flow","parsed","requestToken","requestUrl","consumerKey","clientCredential","request","authorizeUrl","encodeURIComponent","oauth_token","startOAuth2Flow","state","generateState","buildAuthorizeUrl","handleOAuth1Callback","oauthToken","oauth_verifier","oauthVerifier","query","Error","accessToken","accessUrl","oauthTokenCredential","oauth_token_secret","handleOAuth2Callback","code","queryState","error","error_description","errorDescription","exchangeAuthorizationCode","createOAuthConnectMiddleware","next","strapi","config","get","throw","storedProviders","store","type","enabled","ApplicationError","getService","require$$5","buildRedirectUri","callbackOverride","oauthConnect","effectiveConfig","err","message"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import require$$1 from '@strapi/utils';
|
|
|
2
2
|
import { __require as requireProviders } from './providers.mjs';
|
|
3
3
|
import { __require as requireOauth1 } from './oauth1.mjs';
|
|
4
4
|
import { __require as requireOauth2 } from './oauth2.mjs';
|
|
5
|
+
import { __require as requireTrimGrantSessionResponse } from '../trim-grant-session-response.mjs';
|
|
5
6
|
import { __require as requireUtils } from '../index.mjs';
|
|
6
7
|
|
|
7
8
|
var oauthConnect;
|
|
@@ -13,6 +14,7 @@ function requireOauthConnect() {
|
|
|
13
14
|
const builtinProviderEndpoints = requireProviders();
|
|
14
15
|
const oauth1 = requireOauth1();
|
|
15
16
|
const oauth2 = requireOauth2();
|
|
17
|
+
const { trimGrantSessionResponse } = requireTrimGrantSessionResponse();
|
|
16
18
|
const CONNECT_PREFIX = '/connect';
|
|
17
19
|
const parseConnectPath = (requestPath, apiPrefix)=>{
|
|
18
20
|
const prefix = `${apiPrefix}${CONNECT_PREFIX}/`;
|
|
@@ -83,6 +85,13 @@ function requireOauthConnect() {
|
|
|
83
85
|
dynamic
|
|
84
86
|
} : {};
|
|
85
87
|
};
|
|
88
|
+
const redirectWithSessionResponse = (ctx, callbackUrl, provider, tokenResponse)=>{
|
|
89
|
+
const grantResponse = oauth2.tokensToQueryPayload(provider, tokenResponse);
|
|
90
|
+
ctx.session.grant = {
|
|
91
|
+
response: trimGrantSessionResponse(grantResponse, provider.name)
|
|
92
|
+
};
|
|
93
|
+
return redirectWithPayload(ctx, callbackUrl, {});
|
|
94
|
+
};
|
|
86
95
|
const startOAuth1Flow = async (ctx, provider, parsed, redirectUri)=>{
|
|
87
96
|
const requestToken = await oauth1.requestToken({
|
|
88
97
|
requestUrl: provider.request_url,
|
|
@@ -129,9 +138,7 @@ function requireOauthConnect() {
|
|
|
129
138
|
oauthVerifier,
|
|
130
139
|
oauthTokenCredential: requestToken.oauth_token_secret
|
|
131
140
|
});
|
|
132
|
-
|
|
133
|
-
ctx.session.grant = {};
|
|
134
|
-
return redirectWithPayload(ctx, callbackUrl, payload);
|
|
141
|
+
return redirectWithSessionResponse(ctx, callbackUrl, provider, tokenResponse);
|
|
135
142
|
};
|
|
136
143
|
const handleOAuth2Callback = async (ctx, provider, callbackUrl, redirectUri)=>{
|
|
137
144
|
const session = ctx.session.grant || {};
|
|
@@ -157,9 +164,7 @@ function requireOauthConnect() {
|
|
|
157
164
|
code,
|
|
158
165
|
subdomain: provider.subdomain
|
|
159
166
|
});
|
|
160
|
-
|
|
161
|
-
ctx.session.grant = {};
|
|
162
|
-
return redirectWithPayload(ctx, callbackUrl, payload);
|
|
167
|
+
return redirectWithSessionResponse(ctx, callbackUrl, provider, tokenResponse);
|
|
163
168
|
};
|
|
164
169
|
const createOAuthConnectMiddleware = ()=>{
|
|
165
170
|
return async (ctx, next)=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../server/src/utils/oauth-connect/index.js"],"sourcesContent":["'use strict';\n\nconst { errors } = require('@strapi/utils');\n\nconst builtinProviderEndpoints = require('./providers');\nconst oauth1 = require('./oauth1');\nconst oauth2 = require('./oauth2');\n\nconst CONNECT_PREFIX = '/connect';\n\nconst parseConnectPath = (requestPath, apiPrefix) => {\n const prefix = `${apiPrefix}${CONNECT_PREFIX}/`;\n if (!requestPath.startsWith(prefix)) {\n return null;\n }\n\n const remainder = requestPath.slice(prefix.length);\n const [provider, segment] = remainder.split('/').filter(Boolean);\n\n if (!provider) {\n return null;\n }\n\n return {\n provider,\n isCallback: segment === 'callback',\n };\n};\n\n/**\n * Resolve OAuth endpoint config from built-ins, falling back to store-defined\n * endpoints so custom providers registered via providers-registry still work.\n */\nconst buildProviderConfig = (providerName, storedConfig, redirectUri) => {\n const defaults = builtinProviderEndpoints[providerName];\n const endpoints = defaults || {\n oauth: storedConfig.oauth,\n authorize_url: storedConfig.authorize_url,\n access_url: storedConfig.access_url,\n request_url: storedConfig.request_url,\n scope_delimiter: storedConfig.scope_delimiter,\n token_endpoint_auth_method: storedConfig.token_endpoint_auth_method,\n };\n\n if (endpoints.oauth === 1) {\n if (!endpoints.request_url || !endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n } else if (!endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n\n return {\n name: providerName,\n ...endpoints,\n key: storedConfig.key,\n secret: storedConfig.secret,\n scope: storedConfig.scope,\n subdomain: storedConfig.subdomain,\n callback: storedConfig.callback,\n redirect_uri: redirectUri,\n };\n};\n\nconst redirectWithPayload = (ctx, callbackUrl, payload) => {\n const url = new URL(callbackUrl);\n const params = new URLSearchParams();\n\n Object.entries(payload).forEach(([key, value]) => {\n if (key === 'raw') {\n Object.entries(value).forEach(([rawKey, rawValue]) => {\n params.set(`raw[${rawKey}]`, String(rawValue));\n });\n return;\n }\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n });\n\n url.search = params.toString();\n ctx.redirect(url.toString());\n};\n\nconst preserveGrantDynamic = (ctx) => {\n const dynamic = ctx.session.grant?.dynamic;\n return dynamic ? { dynamic } : {};\n};\n\nconst startOAuth1Flow = async (ctx, provider, parsed, redirectUri) => {\n const requestToken = await oauth1.requestToken({\n requestUrl: provider.request_url,\n redirectUri,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n });\n\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n request: requestToken,\n };\n\n const authorizeUrl = `${provider.authorize_url}?oauth_token=${encodeURIComponent(requestToken.oauth_token)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst startOAuth2Flow = (ctx, provider, parsed, redirectUri) => {\n const state = oauth2.generateState();\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n state,\n };\n\n let authorizeUrl = oauth2.buildAuthorizeUrl(provider, {\n key: provider.key,\n redirectUri,\n scope: provider.scope,\n subdomain: provider.subdomain,\n });\n\n authorizeUrl += `&state=${encodeURIComponent(state)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst handleOAuth1Callback = async (ctx, provider, callbackUrl) => {\n const session = ctx.session.grant || {};\n const { oauth_token: oauthToken, oauth_verifier: oauthVerifier } = ctx.query;\n const requestToken = session.request;\n\n if (!requestToken?.oauth_token || oauthToken !== requestToken.oauth_token) {\n throw new Error('OAuth1 token mismatch');\n }\n\n const tokenResponse = await oauth1.accessToken({\n accessUrl: provider.access_url,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n oauthToken,\n oauthVerifier,\n oauthTokenCredential: requestToken.oauth_token_secret,\n });\n\n const payload = oauth2.tokensToQueryPayload(provider, tokenResponse);\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, payload);\n};\n\nconst handleOAuth2Callback = async (ctx, provider, callbackUrl, redirectUri) => {\n const session = ctx.session.grant || {};\n const { code, state: queryState, error, error_description: errorDescription } = ctx.query;\n\n if (error) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error,\n error_description: errorDescription,\n });\n }\n\n if (!code) {\n throw new Error('OAuth2 missing code parameter');\n }\n\n // Reject when session state is missing (not only on mismatch) to close login-CSRF.\n if (!session.state || queryState !== session.state) {\n throw new Error('OAuth2 state mismatch');\n }\n\n const tokenResponse = await oauth2.exchangeAuthorizationCode(provider, {\n key: provider.key,\n secret: provider.secret,\n redirectUri,\n code,\n subdomain: provider.subdomain,\n });\n\n const payload = oauth2.tokensToQueryPayload(provider, tokenResponse);\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, payload);\n};\n\nconst createOAuthConnectMiddleware = () => {\n return async (ctx, next) => {\n const apiPrefix = strapi.config.get('api.rest.prefix');\n const [requestPath] = ctx.request.url.split('?');\n const parsed = parseConnectPath(requestPath, apiPrefix);\n\n if (!parsed) {\n return next();\n }\n\n if (!ctx.session) {\n ctx.throw(400, 'OAuth connect requires session middleware');\n }\n\n const storedProviders = await strapi\n .store({ type: 'plugin', name: 'users-permissions', key: 'grant' })\n .get();\n\n const storedConfig = storedProviders?.[parsed.provider];\n if (!storedConfig?.enabled) {\n throw new errors.ApplicationError('This provider is disabled');\n }\n\n const { getService } = require('..');\n const redirectUri = getService('providers').buildRedirectUri(parsed.provider);\n\n const callbackOverride =\n ctx.state.oauthConnect?.callback ?? ctx.session.grant?.dynamic?.callback;\n const effectiveConfig = callbackOverride\n ? { ...storedConfig, callback: callbackOverride }\n : storedConfig;\n\n const provider = buildProviderConfig(parsed.provider, effectiveConfig, redirectUri);\n\n if (!provider) {\n throw new errors.ApplicationError('Unknown OAuth provider');\n }\n\n ctx.session.grant = ctx.session.grant || {};\n\n if (!parsed.isCallback) {\n if (provider.oauth === 1) {\n return startOAuth1Flow(ctx, provider, parsed, redirectUri);\n }\n return startOAuth2Flow(ctx, provider, parsed, redirectUri);\n }\n\n const callbackUrl = effectiveConfig.callback;\n if (!callbackUrl) {\n throw new errors.ApplicationError('Provider callback URL is not configured');\n }\n\n try {\n if (provider.oauth === 1) {\n return await handleOAuth1Callback(ctx, provider, callbackUrl);\n }\n return await handleOAuth2Callback(ctx, provider, callbackUrl, redirectUri);\n } catch (err) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error: 'oauth_error',\n error_description: err.message,\n });\n }\n };\n};\n\nmodule.exports = {\n createOAuthConnectMiddleware,\n parseConnectPath,\n buildProviderConfig,\n redirectWithPayload,\n};\n"],"names":["errors","require$$0","builtinProviderEndpoints","require$$1","oauth1","require$$2","oauth2","require$$3","CONNECT_PREFIX","parseConnectPath","requestPath","apiPrefix","prefix","startsWith","remainder","slice","length","provider","segment","split","filter","Boolean","isCallback","buildProviderConfig","providerName","storedConfig","redirectUri","defaults","endpoints","oauth","authorize_url","access_url","request_url","scope_delimiter","token_endpoint_auth_method","name","key","secret","scope","subdomain","callback","redirect_uri","redirectWithPayload","ctx","callbackUrl","payload","url","URL","params","URLSearchParams","Object","entries","forEach","value","rawKey","rawValue","set","String","undefined","search","toString","redirect","preserveGrantDynamic","dynamic","session","grant","startOAuth1Flow","parsed","requestToken","requestUrl","consumerKey","clientCredential","request","authorizeUrl","encodeURIComponent","oauth_token","startOAuth2Flow","state","generateState","buildAuthorizeUrl","handleOAuth1Callback","oauthToken","oauth_verifier","oauthVerifier","query","Error","tokenResponse","accessToken","accessUrl","oauthTokenCredential","oauth_token_secret","tokensToQueryPayload","handleOAuth2Callback","code","queryState","error","error_description","errorDescription","exchangeAuthorizationCode","createOAuthConnectMiddleware","next","strapi","config","get","throw","storedProviders","store","type","enabled","ApplicationError","getService","require$$4","buildRedirectUri","callbackOverride","oauthConnect","effectiveConfig","err","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../server/src/utils/oauth-connect/index.js"],"sourcesContent":["'use strict';\n\nconst { errors } = require('@strapi/utils');\n\nconst builtinProviderEndpoints = require('./providers');\nconst oauth1 = require('./oauth1');\nconst oauth2 = require('./oauth2');\nconst { trimGrantSessionResponse } = require('../trim-grant-session-response');\n\nconst CONNECT_PREFIX = '/connect';\n\nconst parseConnectPath = (requestPath, apiPrefix) => {\n const prefix = `${apiPrefix}${CONNECT_PREFIX}/`;\n if (!requestPath.startsWith(prefix)) {\n return null;\n }\n\n const remainder = requestPath.slice(prefix.length);\n const [provider, segment] = remainder.split('/').filter(Boolean);\n\n if (!provider) {\n return null;\n }\n\n return {\n provider,\n isCallback: segment === 'callback',\n };\n};\n\n/**\n * Resolve OAuth endpoint config from built-ins, falling back to store-defined\n * endpoints so custom providers registered via providers-registry still work.\n */\nconst buildProviderConfig = (providerName, storedConfig, redirectUri) => {\n const defaults = builtinProviderEndpoints[providerName];\n const endpoints = defaults || {\n oauth: storedConfig.oauth,\n authorize_url: storedConfig.authorize_url,\n access_url: storedConfig.access_url,\n request_url: storedConfig.request_url,\n scope_delimiter: storedConfig.scope_delimiter,\n token_endpoint_auth_method: storedConfig.token_endpoint_auth_method,\n };\n\n if (endpoints.oauth === 1) {\n if (!endpoints.request_url || !endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n } else if (!endpoints.authorize_url || !endpoints.access_url) {\n return null;\n }\n\n return {\n name: providerName,\n ...endpoints,\n key: storedConfig.key,\n secret: storedConfig.secret,\n scope: storedConfig.scope,\n subdomain: storedConfig.subdomain,\n callback: storedConfig.callback,\n redirect_uri: redirectUri,\n };\n};\n\nconst redirectWithPayload = (ctx, callbackUrl, payload) => {\n const url = new URL(callbackUrl);\n const params = new URLSearchParams();\n\n Object.entries(payload).forEach(([key, value]) => {\n if (key === 'raw') {\n Object.entries(value).forEach(([rawKey, rawValue]) => {\n params.set(`raw[${rawKey}]`, String(rawValue));\n });\n return;\n }\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n });\n\n url.search = params.toString();\n ctx.redirect(url.toString());\n};\n\nconst preserveGrantDynamic = (ctx) => {\n const dynamic = ctx.session.grant?.dynamic;\n return dynamic ? { dynamic } : {};\n};\n\nconst redirectWithSessionResponse = (ctx, callbackUrl, provider, tokenResponse) => {\n const grantResponse = oauth2.tokensToQueryPayload(provider, tokenResponse);\n ctx.session.grant = {\n response: trimGrantSessionResponse(grantResponse, provider.name),\n };\n\n return redirectWithPayload(ctx, callbackUrl, {});\n};\n\nconst startOAuth1Flow = async (ctx, provider, parsed, redirectUri) => {\n const requestToken = await oauth1.requestToken({\n requestUrl: provider.request_url,\n redirectUri,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n });\n\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n request: requestToken,\n };\n\n const authorizeUrl = `${provider.authorize_url}?oauth_token=${encodeURIComponent(requestToken.oauth_token)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst startOAuth2Flow = (ctx, provider, parsed, redirectUri) => {\n const state = oauth2.generateState();\n ctx.session.grant = {\n ...preserveGrantDynamic(ctx),\n provider: parsed.provider,\n state,\n };\n\n let authorizeUrl = oauth2.buildAuthorizeUrl(provider, {\n key: provider.key,\n redirectUri,\n scope: provider.scope,\n subdomain: provider.subdomain,\n });\n\n authorizeUrl += `&state=${encodeURIComponent(state)}`;\n return ctx.redirect(authorizeUrl);\n};\n\nconst handleOAuth1Callback = async (ctx, provider, callbackUrl) => {\n const session = ctx.session.grant || {};\n const { oauth_token: oauthToken, oauth_verifier: oauthVerifier } = ctx.query;\n const requestToken = session.request;\n\n if (!requestToken?.oauth_token || oauthToken !== requestToken.oauth_token) {\n throw new Error('OAuth1 token mismatch');\n }\n\n const tokenResponse = await oauth1.accessToken({\n accessUrl: provider.access_url,\n consumerKey: provider.key,\n clientCredential: provider.secret,\n oauthToken,\n oauthVerifier,\n oauthTokenCredential: requestToken.oauth_token_secret,\n });\n\n return redirectWithSessionResponse(ctx, callbackUrl, provider, tokenResponse);\n};\n\nconst handleOAuth2Callback = async (ctx, provider, callbackUrl, redirectUri) => {\n const session = ctx.session.grant || {};\n const { code, state: queryState, error, error_description: errorDescription } = ctx.query;\n\n if (error) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error,\n error_description: errorDescription,\n });\n }\n\n if (!code) {\n throw new Error('OAuth2 missing code parameter');\n }\n\n // Reject when session state is missing (not only on mismatch) to close login-CSRF.\n if (!session.state || queryState !== session.state) {\n throw new Error('OAuth2 state mismatch');\n }\n\n const tokenResponse = await oauth2.exchangeAuthorizationCode(provider, {\n key: provider.key,\n secret: provider.secret,\n redirectUri,\n code,\n subdomain: provider.subdomain,\n });\n\n return redirectWithSessionResponse(ctx, callbackUrl, provider, tokenResponse);\n};\n\nconst createOAuthConnectMiddleware = () => {\n return async (ctx, next) => {\n const apiPrefix = strapi.config.get('api.rest.prefix');\n const [requestPath] = ctx.request.url.split('?');\n const parsed = parseConnectPath(requestPath, apiPrefix);\n\n if (!parsed) {\n return next();\n }\n\n if (!ctx.session) {\n ctx.throw(400, 'OAuth connect requires session middleware');\n }\n\n const storedProviders = await strapi\n .store({ type: 'plugin', name: 'users-permissions', key: 'grant' })\n .get();\n\n const storedConfig = storedProviders?.[parsed.provider];\n if (!storedConfig?.enabled) {\n throw new errors.ApplicationError('This provider is disabled');\n }\n\n const { getService } = require('..');\n const redirectUri = getService('providers').buildRedirectUri(parsed.provider);\n\n const callbackOverride =\n ctx.state.oauthConnect?.callback ?? ctx.session.grant?.dynamic?.callback;\n const effectiveConfig = callbackOverride\n ? { ...storedConfig, callback: callbackOverride }\n : storedConfig;\n\n const provider = buildProviderConfig(parsed.provider, effectiveConfig, redirectUri);\n\n if (!provider) {\n throw new errors.ApplicationError('Unknown OAuth provider');\n }\n\n ctx.session.grant = ctx.session.grant || {};\n\n if (!parsed.isCallback) {\n if (provider.oauth === 1) {\n return startOAuth1Flow(ctx, provider, parsed, redirectUri);\n }\n return startOAuth2Flow(ctx, provider, parsed, redirectUri);\n }\n\n const callbackUrl = effectiveConfig.callback;\n if (!callbackUrl) {\n throw new errors.ApplicationError('Provider callback URL is not configured');\n }\n\n try {\n if (provider.oauth === 1) {\n return await handleOAuth1Callback(ctx, provider, callbackUrl);\n }\n return await handleOAuth2Callback(ctx, provider, callbackUrl, redirectUri);\n } catch (err) {\n ctx.session.grant = {};\n return redirectWithPayload(ctx, callbackUrl, {\n error: 'oauth_error',\n error_description: err.message,\n });\n }\n };\n};\n\nmodule.exports = {\n createOAuthConnectMiddleware,\n parseConnectPath,\n buildProviderConfig,\n redirectWithPayload,\n};\n"],"names":["errors","require$$0","builtinProviderEndpoints","require$$1","oauth1","require$$2","oauth2","require$$3","trimGrantSessionResponse","require$$4","CONNECT_PREFIX","parseConnectPath","requestPath","apiPrefix","prefix","startsWith","remainder","slice","length","provider","segment","split","filter","Boolean","isCallback","buildProviderConfig","providerName","storedConfig","redirectUri","defaults","endpoints","oauth","authorize_url","access_url","request_url","scope_delimiter","token_endpoint_auth_method","name","key","secret","scope","subdomain","callback","redirect_uri","redirectWithPayload","ctx","callbackUrl","payload","url","URL","params","URLSearchParams","Object","entries","forEach","value","rawKey","rawValue","set","String","undefined","search","toString","redirect","preserveGrantDynamic","dynamic","session","grant","redirectWithSessionResponse","tokenResponse","grantResponse","tokensToQueryPayload","response","startOAuth1Flow","parsed","requestToken","requestUrl","consumerKey","clientCredential","request","authorizeUrl","encodeURIComponent","oauth_token","startOAuth2Flow","state","generateState","buildAuthorizeUrl","handleOAuth1Callback","oauthToken","oauth_verifier","oauthVerifier","query","Error","accessToken","accessUrl","oauthTokenCredential","oauth_token_secret","handleOAuth2Callback","code","queryState","error","error_description","errorDescription","exchangeAuthorizationCode","createOAuthConnectMiddleware","next","strapi","config","get","throw","storedProviders","store","type","enabled","ApplicationError","getService","require$$5","buildRedirectUri","callbackOverride","oauthConnect","effectiveConfig","err","message"],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var trimGrantSessionResponse_1;
|
|
4
|
+
var hasRequiredTrimGrantSessionResponse;
|
|
5
|
+
function requireTrimGrantSessionResponse() {
|
|
6
|
+
if (hasRequiredTrimGrantSessionResponse) return trimGrantSessionResponse_1;
|
|
7
|
+
hasRequiredTrimGrantSessionResponse = 1;
|
|
8
|
+
const compact = (value)=>{
|
|
9
|
+
if (value === null || value === undefined) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry])=>[
|
|
16
|
+
key,
|
|
17
|
+
compact(entry)
|
|
18
|
+
]).filter(([, entry])=>entry !== undefined));
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Compact grant's OAuth token response before it is written to the signed
|
|
22
|
+
* koa-session cookie. The full token exchange payload (especially Cognito's
|
|
23
|
+
* dual JWTs plus a duplicated raw blob) can exceed the browser's ~4 KB
|
|
24
|
+
* per-cookie limit and silently break the auth callback.
|
|
25
|
+
*
|
|
26
|
+
* Keep only fields that auth.callback / providers-registry actually read.
|
|
27
|
+
*/ const trimGrantSessionResponse = (grantResponse, provider)=>{
|
|
28
|
+
if (!grantResponse || typeof grantResponse !== 'object') {
|
|
29
|
+
return grantResponse;
|
|
30
|
+
}
|
|
31
|
+
switch(provider){
|
|
32
|
+
case 'cognito':
|
|
33
|
+
return compact({
|
|
34
|
+
id_token: grantResponse.id_token
|
|
35
|
+
});
|
|
36
|
+
case 'twitter':
|
|
37
|
+
return compact({
|
|
38
|
+
access_token: grantResponse.access_token,
|
|
39
|
+
access_secret: grantResponse.access_secret,
|
|
40
|
+
raw: grantResponse.raw?.screen_name ? {
|
|
41
|
+
screen_name: grantResponse.raw.screen_name
|
|
42
|
+
} : undefined
|
|
43
|
+
});
|
|
44
|
+
case 'vk':
|
|
45
|
+
return compact({
|
|
46
|
+
access_token: grantResponse.access_token,
|
|
47
|
+
raw: grantResponse.raw?.email != null && grantResponse.raw?.user_id != null ? {
|
|
48
|
+
email: grantResponse.raw.email,
|
|
49
|
+
user_id: grantResponse.raw.user_id
|
|
50
|
+
} : undefined
|
|
51
|
+
});
|
|
52
|
+
default:
|
|
53
|
+
return compact({
|
|
54
|
+
access_token: grantResponse.access_token,
|
|
55
|
+
oauth_token: grantResponse.oauth_token,
|
|
56
|
+
id_token: grantResponse.id_token
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
trimGrantSessionResponse_1 = {
|
|
61
|
+
trimGrantSessionResponse
|
|
62
|
+
};
|
|
63
|
+
return trimGrantSessionResponse_1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.__require = requireTrimGrantSessionResponse;
|
|
67
|
+
//# sourceMappingURL=trim-grant-session-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-grant-session-response.js","sources":["../../../server/src/utils/trim-grant-session-response.js"],"sourcesContent":["'use strict';\n\nconst compact = (value) => {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value !== 'object' || Array.isArray(value)) {\n return value;\n }\n\n return Object.fromEntries(\n Object.entries(value)\n .map(([key, entry]) => [key, compact(entry)])\n .filter(([, entry]) => entry !== undefined)\n );\n};\n\n/**\n * Compact grant's OAuth token response before it is written to the signed\n * koa-session cookie. The full token exchange payload (especially Cognito's\n * dual JWTs plus a duplicated raw blob) can exceed the browser's ~4 KB\n * per-cookie limit and silently break the auth callback.\n *\n * Keep only fields that auth.callback / providers-registry actually read.\n */\nconst trimGrantSessionResponse = (grantResponse, provider) => {\n if (!grantResponse || typeof grantResponse !== 'object') {\n return grantResponse;\n }\n\n switch (provider) {\n case 'cognito':\n return compact({\n id_token: grantResponse.id_token,\n });\n\n case 'twitter':\n return compact({\n access_token: grantResponse.access_token,\n access_secret: grantResponse.access_secret,\n raw: grantResponse.raw?.screen_name\n ? { screen_name: grantResponse.raw.screen_name }\n : undefined,\n });\n\n case 'vk':\n return compact({\n access_token: grantResponse.access_token,\n raw:\n grantResponse.raw?.email != null && grantResponse.raw?.user_id != null\n ? {\n email: grantResponse.raw.email,\n user_id: grantResponse.raw.user_id,\n }\n : undefined,\n });\n\n default:\n return compact({\n access_token: grantResponse.access_token,\n oauth_token: grantResponse.oauth_token,\n id_token: grantResponse.id_token,\n });\n }\n};\n\nmodule.exports = {\n trimGrantSessionResponse,\n};\n"],"names":["compact","value","undefined","Array","isArray","Object","fromEntries","entries","map","key","entry","filter","trimGrantSessionResponse","grantResponse","provider","id_token","access_token","access_secret","raw","screen_name","email","user_id","oauth_token","trimGrantSessionResponse_1"],"mappings":";;;;;;;AAEA,IAAA,MAAMA,UAAU,CAACC,KAAAA,GAAAA;QACf,IAAIA,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAUC,SAAAA,EAAW;YACzC,OAAOA,SAAAA;AACX,QAAA;AAEE,QAAA,IAAI,OAAOD,KAAAA,KAAU,QAAA,IAAYE,KAAAA,CAAMC,OAAO,CAACH,KAAAA,CAAAA,EAAQ;YACrD,OAAOA,KAAAA;AACX,QAAA;AAEE,QAAA,OAAOI,MAAAA,CAAOC,WAAW,CACvBD,MAAAA,CAAOE,OAAO,CAACN,KAAAA,CAAAA,CACZO,GAAG,CAAC,CAAC,CAACC,GAAAA,EAAKC,MAAM,GAAK;AAACD,gBAAAA,GAAAA;gBAAKT,OAAAA,CAAQU,KAAAA;AAAO,aAAA,CAAA,CAC3CC,MAAM,CAAC,CAAC,GAAGD,KAAAA,CAAM,GAAKA,KAAAA,KAAUR,SAAAA,CAAAA,CAAAA;AAEvC,IAAA,CAAA;AAEA;;;;;;;KAQA,MAAMU,wBAAAA,GAA2B,CAACC,aAAAA,EAAeC,QAAAA,GAAAA;AAC/C,QAAA,IAAI,CAACD,aAAAA,IAAiB,OAAOA,aAAAA,KAAkB,QAAA,EAAU;YACvD,OAAOA,aAAAA;AACX,QAAA;QAEE,OAAQC,QAAAA;YACN,KAAK,SAAA;AACH,gBAAA,OAAOd,OAAAA,CAAQ;AACbe,oBAAAA,QAAAA,EAAUF,cAAcE;AAChC,iBAAA,CAAA;YAEI,KAAK,SAAA;AACH,gBAAA,OAAOf,OAAAA,CAAQ;AACbgB,oBAAAA,YAAAA,EAAcH,cAAcG,YAAY;AACxCC,oBAAAA,aAAAA,EAAeJ,cAAcI,aAAa;oBAC1CC,GAAAA,EAAKL,aAAAA,CAAcK,GAAG,EAAEC,WAAAA,GACpB;wBAAEA,WAAAA,EAAaN,aAAAA,CAAcK,GAAG,CAACC;qBAAW,GAC5CjB;AACZ,iBAAA,CAAA;YAEI,KAAK,IAAA;AACH,gBAAA,OAAOF,OAAAA,CAAQ;AACbgB,oBAAAA,YAAAA,EAAcH,cAAcG,YAAY;oBACxCE,GAAAA,EACEL,aAAAA,CAAcK,GAAG,EAAEE,KAAAA,IAAS,QAAQP,aAAAA,CAAcK,GAAG,EAAEG,OAAAA,IAAW,IAAA,GAC9D;wBACED,KAAAA,EAAOP,aAAAA,CAAcK,GAAG,CAACE,KAAK;wBAC9BC,OAAAA,EAASR,aAAAA,CAAcK,GAAG,CAACG;qBAC3C,GACcnB;AACd,iBAAA,CAAA;AAEI,YAAA;AACE,gBAAA,OAAOF,OAAAA,CAAQ;AACbgB,oBAAAA,YAAAA,EAAcH,cAAcG,YAAY;AACxCM,oBAAAA,WAAAA,EAAaT,cAAcS,WAAW;AACtCP,oBAAAA,QAAAA,EAAUF,cAAcE;AAChC,iBAAA,CAAA;AACA;AACA,IAAA,CAAA;IAEAQ,0BAAAA,GAAiB;AACfX,QAAAA;AACF,KAAA;;;;;;"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
var trimGrantSessionResponse_1;
|
|
2
|
+
var hasRequiredTrimGrantSessionResponse;
|
|
3
|
+
function requireTrimGrantSessionResponse() {
|
|
4
|
+
if (hasRequiredTrimGrantSessionResponse) return trimGrantSessionResponse_1;
|
|
5
|
+
hasRequiredTrimGrantSessionResponse = 1;
|
|
6
|
+
const compact = (value)=>{
|
|
7
|
+
if (value === null || value === undefined) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry])=>[
|
|
14
|
+
key,
|
|
15
|
+
compact(entry)
|
|
16
|
+
]).filter(([, entry])=>entry !== undefined));
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Compact grant's OAuth token response before it is written to the signed
|
|
20
|
+
* koa-session cookie. The full token exchange payload (especially Cognito's
|
|
21
|
+
* dual JWTs plus a duplicated raw blob) can exceed the browser's ~4 KB
|
|
22
|
+
* per-cookie limit and silently break the auth callback.
|
|
23
|
+
*
|
|
24
|
+
* Keep only fields that auth.callback / providers-registry actually read.
|
|
25
|
+
*/ const trimGrantSessionResponse = (grantResponse, provider)=>{
|
|
26
|
+
if (!grantResponse || typeof grantResponse !== 'object') {
|
|
27
|
+
return grantResponse;
|
|
28
|
+
}
|
|
29
|
+
switch(provider){
|
|
30
|
+
case 'cognito':
|
|
31
|
+
return compact({
|
|
32
|
+
id_token: grantResponse.id_token
|
|
33
|
+
});
|
|
34
|
+
case 'twitter':
|
|
35
|
+
return compact({
|
|
36
|
+
access_token: grantResponse.access_token,
|
|
37
|
+
access_secret: grantResponse.access_secret,
|
|
38
|
+
raw: grantResponse.raw?.screen_name ? {
|
|
39
|
+
screen_name: grantResponse.raw.screen_name
|
|
40
|
+
} : undefined
|
|
41
|
+
});
|
|
42
|
+
case 'vk':
|
|
43
|
+
return compact({
|
|
44
|
+
access_token: grantResponse.access_token,
|
|
45
|
+
raw: grantResponse.raw?.email != null && grantResponse.raw?.user_id != null ? {
|
|
46
|
+
email: grantResponse.raw.email,
|
|
47
|
+
user_id: grantResponse.raw.user_id
|
|
48
|
+
} : undefined
|
|
49
|
+
});
|
|
50
|
+
default:
|
|
51
|
+
return compact({
|
|
52
|
+
access_token: grantResponse.access_token,
|
|
53
|
+
oauth_token: grantResponse.oauth_token,
|
|
54
|
+
id_token: grantResponse.id_token
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
trimGrantSessionResponse_1 = {
|
|
59
|
+
trimGrantSessionResponse
|
|
60
|
+
};
|
|
61
|
+
return trimGrantSessionResponse_1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { requireTrimGrantSessionResponse as __require };
|
|
65
|
+
//# sourceMappingURL=trim-grant-session-response.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trim-grant-session-response.mjs","sources":["../../../server/src/utils/trim-grant-session-response.js"],"sourcesContent":["'use strict';\n\nconst compact = (value) => {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value !== 'object' || Array.isArray(value)) {\n return value;\n }\n\n return Object.fromEntries(\n Object.entries(value)\n .map(([key, entry]) => [key, compact(entry)])\n .filter(([, entry]) => entry !== undefined)\n );\n};\n\n/**\n * Compact grant's OAuth token response before it is written to the signed\n * koa-session cookie. The full token exchange payload (especially Cognito's\n * dual JWTs plus a duplicated raw blob) can exceed the browser's ~4 KB\n * per-cookie limit and silently break the auth callback.\n *\n * Keep only fields that auth.callback / providers-registry actually read.\n */\nconst trimGrantSessionResponse = (grantResponse, provider) => {\n if (!grantResponse || typeof grantResponse !== 'object') {\n return grantResponse;\n }\n\n switch (provider) {\n case 'cognito':\n return compact({\n id_token: grantResponse.id_token,\n });\n\n case 'twitter':\n return compact({\n access_token: grantResponse.access_token,\n access_secret: grantResponse.access_secret,\n raw: grantResponse.raw?.screen_name\n ? { screen_name: grantResponse.raw.screen_name }\n : undefined,\n });\n\n case 'vk':\n return compact({\n access_token: grantResponse.access_token,\n raw:\n grantResponse.raw?.email != null && grantResponse.raw?.user_id != null\n ? {\n email: grantResponse.raw.email,\n user_id: grantResponse.raw.user_id,\n }\n : undefined,\n });\n\n default:\n return compact({\n access_token: grantResponse.access_token,\n oauth_token: grantResponse.oauth_token,\n id_token: grantResponse.id_token,\n });\n }\n};\n\nmodule.exports = {\n trimGrantSessionResponse,\n};\n"],"names":["compact","value","undefined","Array","isArray","Object","fromEntries","entries","map","key","entry","filter","trimGrantSessionResponse","grantResponse","provider","id_token","access_token","access_secret","raw","screen_name","email","user_id","oauth_token","trimGrantSessionResponse_1"],"mappings":";;;;;AAEA,IAAA,MAAMA,UAAU,CAACC,KAAAA,GAAAA;QACf,IAAIA,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAUC,SAAAA,EAAW;YACzC,OAAOA,SAAAA;AACX,QAAA;AAEE,QAAA,IAAI,OAAOD,KAAAA,KAAU,QAAA,IAAYE,KAAAA,CAAMC,OAAO,CAACH,KAAAA,CAAAA,EAAQ;YACrD,OAAOA,KAAAA;AACX,QAAA;AAEE,QAAA,OAAOI,MAAAA,CAAOC,WAAW,CACvBD,MAAAA,CAAOE,OAAO,CAACN,KAAAA,CAAAA,CACZO,GAAG,CAAC,CAAC,CAACC,GAAAA,EAAKC,MAAM,GAAK;AAACD,gBAAAA,GAAAA;gBAAKT,OAAAA,CAAQU,KAAAA;AAAO,aAAA,CAAA,CAC3CC,MAAM,CAAC,CAAC,GAAGD,KAAAA,CAAM,GAAKA,KAAAA,KAAUR,SAAAA,CAAAA,CAAAA;AAEvC,IAAA,CAAA;AAEA;;;;;;;KAQA,MAAMU,wBAAAA,GAA2B,CAACC,aAAAA,EAAeC,QAAAA,GAAAA;AAC/C,QAAA,IAAI,CAACD,aAAAA,IAAiB,OAAOA,aAAAA,KAAkB,QAAA,EAAU;YACvD,OAAOA,aAAAA;AACX,QAAA;QAEE,OAAQC,QAAAA;YACN,KAAK,SAAA;AACH,gBAAA,OAAOd,OAAAA,CAAQ;AACbe,oBAAAA,QAAAA,EAAUF,cAAcE;AAChC,iBAAA,CAAA;YAEI,KAAK,SAAA;AACH,gBAAA,OAAOf,OAAAA,CAAQ;AACbgB,oBAAAA,YAAAA,EAAcH,cAAcG,YAAY;AACxCC,oBAAAA,aAAAA,EAAeJ,cAAcI,aAAa;oBAC1CC,GAAAA,EAAKL,aAAAA,CAAcK,GAAG,EAAEC,WAAAA,GACpB;wBAAEA,WAAAA,EAAaN,aAAAA,CAAcK,GAAG,CAACC;qBAAW,GAC5CjB;AACZ,iBAAA,CAAA;YAEI,KAAK,IAAA;AACH,gBAAA,OAAOF,OAAAA,CAAQ;AACbgB,oBAAAA,YAAAA,EAAcH,cAAcG,YAAY;oBACxCE,GAAAA,EACEL,aAAAA,CAAcK,GAAG,EAAEE,KAAAA,IAAS,QAAQP,aAAAA,CAAcK,GAAG,EAAEG,OAAAA,IAAW,IAAA,GAC9D;wBACED,KAAAA,EAAOP,aAAAA,CAAcK,GAAG,CAACE,KAAK;wBAC9BC,OAAAA,EAASR,aAAAA,CAAcK,GAAG,CAACG;qBAC3C,GACcnB;AACd,iBAAA,CAAA;AAEI,YAAA;AACE,gBAAA,OAAOF,OAAAA,CAAQ;AACbgB,oBAAAA,YAAAA,EAAcH,cAAcG,YAAY;AACxCM,oBAAAA,WAAAA,EAAaT,cAAcS,WAAW;AACtCP,oBAAAA,QAAAA,EAAUF,cAAcE;AAChC,iBAAA,CAAA;AACA;AACA,IAAA,CAAA;IAEAQ,0BAAAA,GAAiB;AACfX,QAAAA;AACF,KAAA;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/plugin-users-permissions",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.53.0",
|
|
4
4
|
"description": "Protect your API with a full-authentication process based on JWT",
|
|
5
5
|
"homepage": "https://strapi.io",
|
|
6
6
|
"bugs": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@strapi/design-system": "2.2.4",
|
|
57
57
|
"@strapi/icons": "2.2.4",
|
|
58
|
-
"@strapi/utils": "5.
|
|
58
|
+
"@strapi/utils": "5.53.0",
|
|
59
59
|
"bcryptjs": "2.4.3",
|
|
60
60
|
"formik": "2.4.9",
|
|
61
61
|
"immer": "9.0.21",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"zod": "4.4.3"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@strapi/admin": "5.
|
|
76
|
-
"@strapi/strapi": "5.
|
|
75
|
+
"@strapi/admin": "5.53.0",
|
|
76
|
+
"@strapi/strapi": "5.53.0",
|
|
77
77
|
"@testing-library/dom": "10.4.1",
|
|
78
78
|
"@testing-library/jest-dom": "6.9.1",
|
|
79
79
|
"@testing-library/react": "16.3.2",
|
|
@@ -205,7 +205,15 @@ module.exports = ({ strapi }) => ({
|
|
|
205
205
|
|
|
206
206
|
// Connect the user with the third-party provider.
|
|
207
207
|
try {
|
|
208
|
-
const
|
|
208
|
+
const grantResponse = _.get(ctx, 'session.grant.response');
|
|
209
|
+
|
|
210
|
+
if (!grantResponse) {
|
|
211
|
+
throw new ApplicationError('OAuth authentication requires a completed provider session');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const user = await getService('providers').connect(provider, grantResponse, {
|
|
215
|
+
grantResponse,
|
|
216
|
+
});
|
|
209
217
|
|
|
210
218
|
if (user.blocked) {
|
|
211
219
|
throw new ForbiddenError('Your account has been blocked by an administrator');
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
const { toPlainObject } = require('lodash/fp');
|
|
4
4
|
|
|
5
5
|
const { checkBadRequest } = require('../../utils');
|
|
6
|
+
const { createRateLimitRunner } = require('./rate-limit');
|
|
6
7
|
|
|
7
8
|
module.exports = ({ nexus, strapi }) => {
|
|
8
9
|
const { nonNull } = nexus;
|
|
10
|
+
const runRateLimit = createRateLimitRunner(strapi, '/auth/change-password');
|
|
9
11
|
|
|
10
12
|
return {
|
|
11
13
|
type: 'UsersPermissionsLoginPayload',
|
|
@@ -21,11 +23,9 @@ module.exports = ({ nexus, strapi }) => {
|
|
|
21
23
|
async resolve(parent, args, context) {
|
|
22
24
|
const { koaContext } = context;
|
|
23
25
|
|
|
24
|
-
koaContext
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const output = koaContext.body;
|
|
26
|
+
const output = await runRateLimit(koaContext, { body: toPlainObject(args) }, (ctx) =>
|
|
27
|
+
strapi.plugin('users-permissions').controller('auth').changePassword(ctx)
|
|
28
|
+
);
|
|
29
29
|
|
|
30
30
|
checkBadRequest(output);
|
|
31
31
|
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
const { toPlainObject } = require('lodash/fp');
|
|
4
4
|
|
|
5
5
|
const { checkBadRequest } = require('../../utils');
|
|
6
|
+
const { createRateLimitRunner } = require('./rate-limit');
|
|
6
7
|
|
|
7
8
|
module.exports = ({ nexus, strapi }) => {
|
|
8
9
|
const { nonNull } = nexus;
|
|
10
|
+
const runRateLimit = createRateLimitRunner(strapi, '/auth/forgot-password');
|
|
9
11
|
|
|
10
12
|
return {
|
|
11
13
|
type: 'UsersPermissionsPasswordPayload',
|
|
@@ -19,11 +21,9 @@ module.exports = ({ nexus, strapi }) => {
|
|
|
19
21
|
async resolve(parent, args, context) {
|
|
20
22
|
const { koaContext } = context;
|
|
21
23
|
|
|
22
|
-
koaContext
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const output = koaContext.body;
|
|
24
|
+
const output = await runRateLimit(koaContext, { body: toPlainObject(args) }, (ctx) =>
|
|
25
|
+
strapi.plugin('users-permissions').controller('auth').forgotPassword(ctx)
|
|
26
|
+
);
|
|
27
27
|
|
|
28
28
|
checkBadRequest(output);
|
|
29
29
|
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
const { toPlainObject } = require('lodash/fp');
|
|
4
4
|
|
|
5
5
|
const { checkBadRequest } = require('../../utils');
|
|
6
|
+
const { createRateLimitRunner } = require('./rate-limit');
|
|
6
7
|
|
|
7
8
|
module.exports = ({ nexus, strapi }) => {
|
|
8
9
|
const { nonNull } = nexus;
|
|
10
|
+
const runRateLimit = createRateLimitRunner(strapi, '/auth/local');
|
|
9
11
|
|
|
10
12
|
return {
|
|
11
13
|
type: nonNull('UsersPermissionsLoginPayload'),
|
|
@@ -17,12 +19,14 @@ module.exports = ({ nexus, strapi }) => {
|
|
|
17
19
|
async resolve(parent, args, context) {
|
|
18
20
|
const { koaContext } = context;
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const output = await runRateLimit(
|
|
23
|
+
koaContext,
|
|
24
|
+
{
|
|
25
|
+
body: toPlainObject(args.input),
|
|
26
|
+
params: { provider: args.input.provider },
|
|
27
|
+
},
|
|
28
|
+
(ctx) => strapi.plugin('users-permissions').controller('auth').callback(ctx)
|
|
29
|
+
);
|
|
26
30
|
|
|
27
31
|
checkBadRequest(output);
|
|
28
32
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const RATE_LIMIT_MIDDLEWARE = 'plugin::users-permissions.rateLimit';
|
|
4
|
+
const contextQueues = new WeakMap();
|
|
5
|
+
|
|
6
|
+
const getRateLimitPath = (strapi, routeSuffix) => {
|
|
7
|
+
const configuredPrefix = strapi.config.get('api.rest.prefix', '/api');
|
|
8
|
+
const prefix = typeof configuredPrefix === 'string' ? configuredPrefix : '/api';
|
|
9
|
+
const normalizedPrefix = prefix.replace(/^\/+|\/+$/g, '');
|
|
10
|
+
const normalizedSuffix = routeSuffix.replace(/^\/+/, '');
|
|
11
|
+
|
|
12
|
+
return `/${[normalizedPrefix, normalizedSuffix].filter(Boolean).join('/')}`;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const enqueueContextOperation = (koaContext, operation) => {
|
|
16
|
+
const previous = contextQueues.get(koaContext) || Promise.resolve();
|
|
17
|
+
const result = previous.catch(() => undefined).then(operation);
|
|
18
|
+
|
|
19
|
+
contextQueues.set(
|
|
20
|
+
koaContext,
|
|
21
|
+
result.catch(() => undefined)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const createRateLimitRunner = (strapi, routeSuffix) => {
|
|
28
|
+
const rateLimit = strapi.middleware(RATE_LIMIT_MIDDLEWARE)({}, { strapi });
|
|
29
|
+
const routePath = getRateLimitPath(strapi, routeSuffix);
|
|
30
|
+
|
|
31
|
+
return (koaContext, { body, params }, controller) =>
|
|
32
|
+
enqueueContextOperation(koaContext, async () => {
|
|
33
|
+
const originalBody = koaContext.request.body;
|
|
34
|
+
const originalPath = koaContext.request.path;
|
|
35
|
+
const originalParams = koaContext.params;
|
|
36
|
+
const originalResponseBody = koaContext.body;
|
|
37
|
+
let responseStatus = 200;
|
|
38
|
+
|
|
39
|
+
koaContext.request.path = routePath;
|
|
40
|
+
koaContext.request.body = body;
|
|
41
|
+
if (params) {
|
|
42
|
+
koaContext.params = params;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
await rateLimit(koaContext, () => controller(koaContext));
|
|
47
|
+
responseStatus = koaContext.status;
|
|
48
|
+
return koaContext.body;
|
|
49
|
+
} finally {
|
|
50
|
+
koaContext.request.path = originalPath;
|
|
51
|
+
koaContext.request.body = originalBody;
|
|
52
|
+
koaContext.params = originalParams;
|
|
53
|
+
koaContext.body = originalResponseBody;
|
|
54
|
+
koaContext.status = responseStatus;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
module.exports = {
|
|
60
|
+
createRateLimitRunner,
|
|
61
|
+
getRateLimitPath,
|
|
62
|
+
};
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
const { toPlainObject } = require('lodash/fp');
|
|
4
4
|
|
|
5
5
|
const { checkBadRequest } = require('../../utils');
|
|
6
|
+
const { createRateLimitRunner } = require('./rate-limit');
|
|
6
7
|
|
|
7
8
|
module.exports = ({ nexus, strapi }) => {
|
|
8
9
|
const { nonNull } = nexus;
|
|
10
|
+
const runRateLimit = createRateLimitRunner(strapi, '/auth/local/register');
|
|
9
11
|
|
|
10
12
|
return {
|
|
11
13
|
type: nonNull('UsersPermissionsLoginPayload'),
|
|
@@ -19,11 +21,9 @@ module.exports = ({ nexus, strapi }) => {
|
|
|
19
21
|
async resolve(parent, args, context) {
|
|
20
22
|
const { koaContext } = context;
|
|
21
23
|
|
|
22
|
-
koaContext
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const output = koaContext.body;
|
|
24
|
+
const output = await runRateLimit(koaContext, { body: toPlainObject(args.input) }, (ctx) =>
|
|
25
|
+
strapi.plugin('users-permissions').controller('auth').register(ctx)
|
|
26
|
+
);
|
|
27
27
|
|
|
28
28
|
checkBadRequest(output);
|
|
29
29
|
|