@strapi/plugin-users-permissions 4.6.0-beta.2 → 4.6.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.
@@ -173,6 +173,21 @@ const forms = {
173
173
  },
174
174
  },
175
175
  ],
176
+ [
177
+ {
178
+ intlLabel: {
179
+ id: getTrad({ id: 'PopUpForm.Providers.jwksurl.label' }),
180
+ defaultMessage: 'JWKS URL',
181
+ },
182
+ name: 'jwksurl',
183
+ type: 'text',
184
+ placeholder: textPlaceholder,
185
+ size: 12,
186
+ validations: {
187
+ required: false,
188
+ },
189
+ },
190
+ ],
176
191
 
177
192
  [
178
193
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/plugin-users-permissions",
3
- "version": "4.6.0-beta.2",
3
+ "version": "4.6.0",
4
4
  "description": "Protect your API with a full-authentication process based on JWT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,11 +27,12 @@
27
27
  "test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
28
28
  },
29
29
  "dependencies": {
30
- "@strapi/helper-plugin": "4.6.0-beta.2",
31
- "@strapi/utils": "4.6.0-beta.2",
30
+ "@strapi/helper-plugin": "4.6.0",
31
+ "@strapi/utils": "4.6.0",
32
32
  "bcryptjs": "2.4.3",
33
33
  "grant-koa": "5.4.8",
34
34
  "jsonwebtoken": "9.0.0",
35
+ "jwk-to-pem": "2.0.5",
35
36
  "koa": "^2.13.4",
36
37
  "koa2-ratelimit": "^1.1.2",
37
38
  "lodash": "4.17.21",
@@ -64,5 +65,5 @@
64
65
  "required": true,
65
66
  "kind": "plugin"
66
67
  },
67
- "gitHead": "b852090f931cd21868c4016f24db2f9fdfc7a7ab"
68
+ "gitHead": "a9e55435c489f3379d88565bf3f729deb29bfb45"
68
69
  }
@@ -2,6 +2,48 @@
2
2
 
3
3
  const { strict: assert } = require('assert');
4
4
  const jwt = require('jsonwebtoken');
5
+ const jwkToPem = require('jwk-to-pem');
6
+
7
+ const getCognitoPayload = async ({ idToken, jwksUrl, purest }) => {
8
+ const {
9
+ header: { kid },
10
+ payload,
11
+ } = jwt.decode(idToken, { complete: true });
12
+
13
+ if (!payload || !kid) {
14
+ throw new Error('The provided token is not valid');
15
+ }
16
+
17
+ const config = {
18
+ cognito: {
19
+ discovery: {
20
+ origin: jwksUrl.origin,
21
+ path: jwksUrl.pathname,
22
+ },
23
+ },
24
+ };
25
+ try {
26
+ const cognito = purest({ provider: 'cognito', config });
27
+ // get the JSON Web Key (JWK) for the user pool
28
+ const { body: jwk } = await cognito('discovery').request();
29
+ // Get the key with the same Key ID as the provided token
30
+ const key = jwk.keys.find(({ kid: jwkKid }) => jwkKid === kid);
31
+ const pem = jwkToPem(key);
32
+
33
+ // https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
34
+ const decodedToken = await new Promise((resolve, reject) => {
35
+ jwt.verify(idToken, pem, { algorithms: ['RS256'] }, (err, decodedToken) => {
36
+ if (err) {
37
+ reject();
38
+ }
39
+ resolve(decodedToken);
40
+ });
41
+ });
42
+ return decodedToken;
43
+ } catch (err) {
44
+ throw new Error('There was an error verifying the token');
45
+ }
46
+ };
5
47
 
6
48
  const getInitialProviders = ({ purest }) => ({
7
49
  async discord({ accessToken }) {
@@ -19,19 +61,14 @@ const getInitialProviders = ({ purest }) => ({
19
61
  };
20
62
  });
21
63
  },
22
- async cognito({ query }) {
23
- // get the id_token
64
+ async cognito({ query, providers }) {
65
+ const jwksUrl = new URL(providers.cognito.jwksurl);
24
66
  const idToken = query.id_token;
25
- // decode the jwt token
26
- const tokenPayload = jwt.decode(idToken);
27
- if (!tokenPayload) {
28
- throw new Error('unable to decode jwt token');
29
- } else {
30
- return {
31
- username: tokenPayload['cognito:username'],
32
- email: tokenPayload.email,
33
- };
34
- }
67
+ const tokenPayload = await getCognitoPayload({ idToken, jwksUrl, purest });
68
+ return {
69
+ username: tokenPayload['cognito:username'],
70
+ email: tokenPayload.email,
71
+ };
35
72
  },
36
73
  async facebook({ accessToken }) {
37
74
  const facebook = purest({ provider: 'facebook' });