@scayle/storefront-core 7.47.0 → 7.48.1
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/CHANGELOG.md +30 -4
- package/dist/helpers/sanitizationHelpers.cjs +1 -1
- package/dist/helpers/sanitizationHelpers.mjs +1 -1
- package/dist/rpc/methods/oauth/idp.cjs +27 -26
- package/dist/rpc/methods/oauth/idp.d.ts +5 -3
- package/dist/rpc/methods/oauth/idp.mjs +21 -26
- package/dist/rpc/methods/session.cjs +3 -1
- package/dist/rpc/methods/session.d.ts +2 -1
- package/dist/rpc/methods/session.mjs +1 -1
- package/dist/utils/keys.d.ts +4 -4
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 7.48.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated `purifySensitiveData` to ensure that empty secrets are logged as empty strings, enhancing clarity in logged configurations.
|
|
8
|
+
|
|
9
|
+
## 7.48.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Add support for dynamically adding query parameters to the IDP redirect callback URLs to be read back when the user returns from the IDP.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const { data: externalIDPRedirects } = await useIDP({
|
|
17
|
+
queryParams: { redirectTo: "/account" },
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Please note that `code` and `state` are not supported as these are used by the SCAYLE Authentication API.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Added merge basket and merge wishlist functionality after login with IDP
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @aboutyou/backbone@16.2.1
|
|
28
|
+
|
|
3
29
|
## 7.47.0
|
|
4
30
|
|
|
5
31
|
### Minor Changes
|
|
@@ -606,7 +632,7 @@
|
|
|
606
632
|
|
|
607
633
|
```js
|
|
608
634
|
env: {
|
|
609
|
-
SFC_OMIT_MD5: true
|
|
635
|
+
SFC_OMIT_MD5: true;
|
|
610
636
|
}
|
|
611
637
|
```
|
|
612
638
|
|
|
@@ -614,7 +640,7 @@
|
|
|
614
640
|
|
|
615
641
|
```js
|
|
616
642
|
env: {
|
|
617
|
-
SFC_OMIT_MD5: process.env.SFC_OMIT_MD5
|
|
643
|
+
SFC_OMIT_MD5: process.env.SFC_OMIT_MD5;
|
|
618
644
|
}
|
|
619
645
|
```
|
|
620
646
|
|
|
@@ -652,7 +678,7 @@
|
|
|
652
678
|
|
|
653
679
|
```js
|
|
654
680
|
env: {
|
|
655
|
-
SFC_OMIT_MD5: true
|
|
681
|
+
SFC_OMIT_MD5: true;
|
|
656
682
|
}
|
|
657
683
|
```
|
|
658
684
|
|
|
@@ -660,7 +686,7 @@
|
|
|
660
686
|
|
|
661
687
|
```js
|
|
662
688
|
env: {
|
|
663
|
-
SFC_OMIT_MD5: process.env.SFC_OMIT_MD5
|
|
689
|
+
SFC_OMIT_MD5: process.env.SFC_OMIT_MD5;
|
|
664
690
|
}
|
|
665
691
|
```
|
|
666
692
|
|
|
@@ -15,7 +15,7 @@ const purifySensitiveData = (data = {}, blacklistedKeys = ["password"]) => {
|
|
|
15
15
|
return purifiedPayload;
|
|
16
16
|
}
|
|
17
17
|
const isSensitiveData = blacklistedKeys.some(excludedKey => key.includes(excludedKey));
|
|
18
|
-
purifiedPayload[key] = isSensitiveData ? SANITIZATION_MASK : value;
|
|
18
|
+
purifiedPayload[key] = isSensitiveData && value !== "" ? SANITIZATION_MASK : value;
|
|
19
19
|
return purifiedPayload;
|
|
20
20
|
}, {});
|
|
21
21
|
};
|
|
@@ -11,7 +11,7 @@ export const purifySensitiveData = (data = {}, blacklistedKeys = ["password"]) =
|
|
|
11
11
|
const isSensitiveData = blacklistedKeys.some(
|
|
12
12
|
(excludedKey) => key.includes(excludedKey)
|
|
13
13
|
);
|
|
14
|
-
purifiedPayload[key] = isSensitiveData ? SANITIZATION_MASK : value;
|
|
14
|
+
purifiedPayload[key] = isSensitiveData && value !== "" ? SANITIZATION_MASK : value;
|
|
15
15
|
return purifiedPayload;
|
|
16
16
|
},
|
|
17
17
|
{}
|
|
@@ -7,36 +7,44 @@ exports.handleIDPLoginCallback = exports.getExternalIdpRedirect = void 0;
|
|
|
7
7
|
var _jose = require("jose");
|
|
8
8
|
var _types = require("../../../types/index.cjs");
|
|
9
9
|
var _oauth = require("../../../api/oauth.cjs");
|
|
10
|
-
var
|
|
11
|
-
const getExternalIdpRedirect = exports.getExternalIdpRedirect = async function getExternalIdpRedirect2(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const checkoutSecret = context.checkout.secret;
|
|
10
|
+
var _session = require("../session.cjs");
|
|
11
|
+
const getExternalIdpRedirect = exports.getExternalIdpRedirect = async function getExternalIdpRedirect2({
|
|
12
|
+
queryParams
|
|
13
|
+
}, context) {
|
|
15
14
|
if (!context.idp?.enabled) {
|
|
16
15
|
return {};
|
|
17
16
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
if (context.idp.idpKeys.length === 0) {
|
|
18
|
+
return new Response("No IDP keys are configured", {
|
|
19
|
+
status: 400
|
|
20
|
+
});
|
|
22
21
|
}
|
|
23
|
-
if (!
|
|
24
|
-
|
|
22
|
+
if (!context.idp.idpRedirectURL) {
|
|
23
|
+
return new Response("No IDP redirect url is configured", {
|
|
24
|
+
status: 400
|
|
25
|
+
});
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const OAuthClient = (0, _oauth.getOAuthClient)(context);
|
|
28
|
+
const redirectUrl = new URL(context.idp.idpRedirectURL);
|
|
29
|
+
if (queryParams) {
|
|
30
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
31
|
+
redirectUrl.searchParams.set(key, value);
|
|
32
|
+
}
|
|
28
33
|
}
|
|
29
|
-
const secret = new TextEncoder().encode(
|
|
30
|
-
const results = await Promise.all(
|
|
34
|
+
const secret = new TextEncoder().encode(context.checkout.secret);
|
|
35
|
+
const results = await Promise.all(context.idp.idpKeys.map(async idpKey => {
|
|
31
36
|
const jwtPayload = await new _jose.SignJWT({
|
|
32
37
|
idpKey,
|
|
33
|
-
callbackUrl:
|
|
38
|
+
callbackUrl: redirectUrl.toString(),
|
|
34
39
|
clientId: OAuthClient.clientId.toString()
|
|
35
40
|
}).setProtectedHeader({
|
|
36
41
|
alg: "HS256",
|
|
37
42
|
typ: "JWT"
|
|
38
43
|
}).setIssuedAt().setExpirationTime("2h").sign(secret);
|
|
39
|
-
|
|
44
|
+
const url = new URL(`${OAuthClient.baseURL}/auth/external/redirect`);
|
|
45
|
+
url.searchParams.set("shopId", `${context.shopId}`);
|
|
46
|
+
url.searchParams.set("jwt", jwtPayload);
|
|
47
|
+
return [idpKey, url.toString()];
|
|
40
48
|
}));
|
|
41
49
|
return Object.fromEntries(results);
|
|
42
50
|
};
|
|
@@ -44,15 +52,8 @@ const handleIDPLoginCallback = exports.handleIDPLoginCallback = async function h
|
|
|
44
52
|
(0, _types.assertSession)(context);
|
|
45
53
|
const OAuthClient = (0, _oauth.getOAuthClient)(context);
|
|
46
54
|
const code = typeof payload === "string" ? payload : payload.code;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
refresh_token: refreshToken
|
|
50
|
-
} = await OAuthClient.generateToken(code);
|
|
51
|
-
context.updateTokens({
|
|
52
|
-
accessToken,
|
|
53
|
-
refreshToken
|
|
54
|
-
});
|
|
55
|
-
await (0, _user.refreshUser)(context);
|
|
55
|
+
const tokens = await OAuthClient.generateToken(code);
|
|
56
|
+
await (0, _session.postLogin)(context, tokens);
|
|
56
57
|
return {
|
|
57
58
|
message: "success"
|
|
58
59
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { RpcContext } from '../../../types';
|
|
2
|
-
export declare const getExternalIdpRedirect: (
|
|
2
|
+
export declare const getExternalIdpRedirect: ({ queryParams }: {
|
|
3
|
+
queryParams?: Record<string, string>;
|
|
4
|
+
}, context: RpcContext) => Promise<Response | {
|
|
3
5
|
[k: string]: string;
|
|
4
6
|
}>;
|
|
5
|
-
export declare const handleIDPLoginCallback: (payload:
|
|
7
|
+
export declare const handleIDPLoginCallback: (payload: {
|
|
6
8
|
code: string;
|
|
7
|
-
}, context: RpcContext) => Promise<{
|
|
9
|
+
} | string, context: RpcContext) => Promise<{
|
|
8
10
|
message: string;
|
|
9
11
|
}>;
|
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
import { SignJWT } from "jose";
|
|
2
2
|
import { assertSession } from "../../../types/index.mjs";
|
|
3
3
|
import { getOAuthClient } from "../../../api/oauth.mjs";
|
|
4
|
-
import {
|
|
5
|
-
export const getExternalIdpRedirect = async function getExternalIdpRedirect2(context) {
|
|
6
|
-
const shopId = context.shopId.toString();
|
|
7
|
-
const OAuthClient = getOAuthClient(context);
|
|
8
|
-
const checkoutSecret = context.checkout.secret;
|
|
4
|
+
import { postLogin } from "../session.mjs";
|
|
5
|
+
export const getExternalIdpRedirect = async function getExternalIdpRedirect2({ queryParams }, context) {
|
|
9
6
|
if (!context.idp?.enabled) {
|
|
10
7
|
return {};
|
|
11
8
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (!IDPKeys.length) {
|
|
15
|
-
throw new Error("No IDP keys configured");
|
|
9
|
+
if (context.idp.idpKeys.length === 0) {
|
|
10
|
+
return new Response("No IDP keys are configured", { status: 400 });
|
|
16
11
|
}
|
|
17
|
-
if (!
|
|
18
|
-
|
|
12
|
+
if (!context.idp.idpRedirectURL) {
|
|
13
|
+
return new Response("No IDP redirect url is configured", { status: 400 });
|
|
19
14
|
}
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
const OAuthClient = getOAuthClient(context);
|
|
16
|
+
const redirectUrl = new URL(context.idp.idpRedirectURL);
|
|
17
|
+
if (queryParams) {
|
|
18
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
19
|
+
redirectUrl.searchParams.set(key, value);
|
|
20
|
+
}
|
|
22
21
|
}
|
|
23
|
-
const secret = new TextEncoder().encode(
|
|
22
|
+
const secret = new TextEncoder().encode(context.checkout.secret);
|
|
24
23
|
const results = await Promise.all(
|
|
25
|
-
|
|
24
|
+
context.idp.idpKeys.map(async (idpKey) => {
|
|
26
25
|
const jwtPayload = await new SignJWT({
|
|
27
26
|
idpKey,
|
|
28
|
-
callbackUrl:
|
|
27
|
+
callbackUrl: redirectUrl.toString(),
|
|
29
28
|
clientId: OAuthClient.clientId.toString()
|
|
30
29
|
}).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setExpirationTime("2h").sign(secret);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
];
|
|
30
|
+
const url = new URL(`${OAuthClient.baseURL}/auth/external/redirect`);
|
|
31
|
+
url.searchParams.set("shopId", `${context.shopId}`);
|
|
32
|
+
url.searchParams.set("jwt", jwtPayload);
|
|
33
|
+
return [idpKey, url.toString()];
|
|
35
34
|
})
|
|
36
35
|
);
|
|
37
36
|
return Object.fromEntries(results);
|
|
@@ -40,12 +39,8 @@ export const handleIDPLoginCallback = async function handleIDPLoginCallback2(pay
|
|
|
40
39
|
assertSession(context);
|
|
41
40
|
const OAuthClient = getOAuthClient(context);
|
|
42
41
|
const code = typeof payload === "string" ? payload : payload.code;
|
|
43
|
-
const
|
|
44
|
-
context
|
|
45
|
-
accessToken,
|
|
46
|
-
refreshToken
|
|
47
|
-
});
|
|
48
|
-
await refreshUser(context);
|
|
42
|
+
const tokens = await OAuthClient.generateToken(code);
|
|
43
|
+
await postLogin(context, tokens);
|
|
49
44
|
return {
|
|
50
45
|
message: "success"
|
|
51
46
|
};
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.oauthRevokeToken = exports.oauthRegister = exports.oauthLogin = exports.oauthGuestLogin = exports.oauthForgetPassword = void 0;
|
|
7
|
+
exports.postLogin = postLogin;
|
|
8
|
+
exports.updatePasswordByHash = exports.refreshAccessToken = void 0;
|
|
7
9
|
var _jose = require("jose");
|
|
8
10
|
var _types = require("../../types/index.cjs");
|
|
9
11
|
var _constants = require("../../constants/index.cjs");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Optional } from 'utility-types';
|
|
2
|
-
import type { GuestRequest, LoginRequest, RegisterRequest, RpcContext, UpdatePasswordByHashRequest } from '../../types';
|
|
2
|
+
import type { GuestRequest, LoginRequest, Oauth, RegisterRequest, RpcContext, RpcContextWithSession, UpdatePasswordByHashRequest } from '../../types';
|
|
3
|
+
export declare function postLogin(context: RpcContextWithSession, tokens: Oauth): Promise<void>;
|
|
3
4
|
export declare const oauthLogin: (login: Optional<LoginRequest, "shop_id">, context: RpcContext) => Promise<Response>;
|
|
4
5
|
export declare const oauthRegister: (register: Optional<RegisterRequest, "shop_id">, context: RpcContext) => Promise<Response>;
|
|
5
6
|
export declare const oauthGuestLogin: (guest: Optional<GuestRequest, "shop_id">, context: RpcContext) => Promise<Response>;
|
|
@@ -11,7 +11,7 @@ const convertErrorForRpcCall = (error, httpStatuses) => {
|
|
|
11
11
|
return new Response(null, { status: error.response.status });
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
async function postLogin(context, tokens) {
|
|
14
|
+
export async function postLogin(context, tokens) {
|
|
15
15
|
const user = await unwrap(
|
|
16
16
|
fetchUser({ accessToken: tokens.access_token, callback: "" }, context)
|
|
17
17
|
);
|
package/dist/utils/keys.d.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import type { Log } from '..';
|
|
2
2
|
import { HashAlgorithm } from '../constants/hash';
|
|
3
3
|
export declare const generateKey: ({ keyTemplate, hashAlgorithm, shopId, userId, log, }: {
|
|
4
|
-
keyName?: string
|
|
4
|
+
keyName?: string;
|
|
5
5
|
keyTemplate: string;
|
|
6
6
|
hashAlgorithm: HashAlgorithm;
|
|
7
7
|
shopId: string;
|
|
8
8
|
userId: string;
|
|
9
|
-
log?: Log
|
|
9
|
+
log?: Log;
|
|
10
10
|
}) => Promise<string>;
|
|
11
11
|
export declare const generateWishlistKey: ({ keyTemplate, hashAlgorithm, shopId, userId, log, }: {
|
|
12
12
|
keyTemplate: string;
|
|
13
13
|
hashAlgorithm: HashAlgorithm;
|
|
14
14
|
shopId: string;
|
|
15
15
|
userId: string;
|
|
16
|
-
log?: Log
|
|
16
|
+
log?: Log;
|
|
17
17
|
}) => Promise<string>;
|
|
18
18
|
export declare const generateBasketKey: ({ keyTemplate, hashAlgorithm, shopId, userId, log, }: {
|
|
19
19
|
keyTemplate: string;
|
|
20
20
|
hashAlgorithm: HashAlgorithm;
|
|
21
21
|
shopId: string;
|
|
22
22
|
userId: string;
|
|
23
|
-
log?: Log
|
|
23
|
+
log?: Log;
|
|
24
24
|
}) => Promise<string>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-core",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.48.1",
|
|
4
4
|
"description": "Collection of essential utilities to work with the Storefront API",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"test:ci": "vitest --run --passWithNoTests --coverage --reporter=default --reporter=junit"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@aboutyou/backbone": "16.2.
|
|
62
|
+
"@aboutyou/backbone": "16.2.1",
|
|
63
63
|
"crypto-js": "4.2.0",
|
|
64
|
-
"jose": "5.2.
|
|
64
|
+
"jose": "5.2.4",
|
|
65
65
|
"radash": "12.1.0",
|
|
66
66
|
"slugify": "1.6.6",
|
|
67
67
|
"ufo": "1.5.3",
|
|
@@ -69,18 +69,18 @@
|
|
|
69
69
|
"utility-types": "3.11.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@scayle/eslint-config-storefront": "3.2.
|
|
72
|
+
"@scayle/eslint-config-storefront": "3.2.7",
|
|
73
73
|
"@types/crypto-js": "4.2.2",
|
|
74
|
-
"@types/node": "20.12.
|
|
74
|
+
"@types/node": "20.12.7",
|
|
75
75
|
"@types/webpack-env": "1.18.4",
|
|
76
76
|
"@vitest/coverage-v8": "1.4.0",
|
|
77
|
-
"dprint": "0.45.
|
|
77
|
+
"dprint": "0.45.1",
|
|
78
78
|
"eslint": "8.57.0",
|
|
79
79
|
"eslint-formatter-gitlab": "5.1.0",
|
|
80
80
|
"publint": "0.2.7",
|
|
81
81
|
"rimraf": "5.0.5",
|
|
82
82
|
"ts-node": "10.9.2",
|
|
83
|
-
"typescript": "5.4.
|
|
83
|
+
"typescript": "5.4.5",
|
|
84
84
|
"unbuild": "2.0.0",
|
|
85
85
|
"unstorage": "1.10.2",
|
|
86
86
|
"vitest": "1.4.0"
|