@shop-on/customer-runtime 0.4.0 → 0.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.
- package/dist/internal-api.d.ts +21 -0
- package/dist/relay.d.ts +6 -0
- package/dist/relay.js +15 -1
- package/dist/session-cookie.d.ts +8 -0
- package/dist/session-cookie.js +5 -5
- package/package.json +2 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/internal-api.d.ts
|
|
2
|
+
export declare class InternalApiError extends Error {
|
|
3
|
+
readonly status: number;
|
|
4
|
+
readonly bodySnippet: string;
|
|
5
|
+
constructor(path: string, status: number, bodySnippet: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* POST a JSON body to `/api/internal/customer/<path>`. Throws
|
|
9
|
+
* `InternalApiError` on non-2xx so callers can decide how to map status →
|
|
10
|
+
* domain outcome (e.g. token mint maps 404 → CredentialsUnavailableError).
|
|
11
|
+
*/
|
|
12
|
+
export declare function internalPost<TResponse>(path: string, body: unknown, { signal }?: {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}): Promise<TResponse>;
|
|
15
|
+
/**
|
|
16
|
+
* DELETE `/api/internal/customer/<path>`. Used by the handoff consume path —
|
|
17
|
+
* the endpoint always returns 200 (with `{ ok: false, reason }` on miss), so
|
|
18
|
+
* a non-2xx here is a real error, not a domain miss.
|
|
19
|
+
*/
|
|
20
|
+
export declare function internalDelete<TResponse>(path: string): Promise<TResponse>;
|
|
21
|
+
//#endregion
|
package/dist/relay.d.ts
CHANGED
|
@@ -5,4 +5,10 @@
|
|
|
5
5
|
* a request or without a valid IP. Spread these last into outgoing headers.
|
|
6
6
|
*/
|
|
7
7
|
export declare function relayHeaders(): Record<string, string>;
|
|
8
|
+
/**
|
|
9
|
+
* `X-Client-IP` from `CF-Connecting-IP` plus `X-Relay-Auth`, for the developers
|
|
10
|
+
* and platform Workers' api calls. Empty without SPN_STAFF_RELAY_SECRET, outside
|
|
11
|
+
* a request, or without a valid IP: with no secret Rails would ignore the IP.
|
|
12
|
+
*/
|
|
13
|
+
export declare function staffRelayHeaders(): Record<string, string>;
|
|
8
14
|
//#endregion
|
package/dist/relay.js
CHANGED
|
@@ -20,5 +20,19 @@ function relayHeaders() {
|
|
|
20
20
|
"X-Relay-Auth": secret
|
|
21
21
|
} : { "X-Buyer-IP": ip };
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* `X-Client-IP` from `CF-Connecting-IP` plus `X-Relay-Auth`, for the developers
|
|
25
|
+
* and platform Workers' api calls. Empty without SPN_STAFF_RELAY_SECRET, outside
|
|
26
|
+
* a request, or without a valid IP: with no secret Rails would ignore the IP.
|
|
27
|
+
*/
|
|
28
|
+
function staffRelayHeaders() {
|
|
29
|
+
const secret = process.env.SPN_STAFF_RELAY_SECRET;
|
|
30
|
+
const ip = currentRequest()?.headers.get("cf-connecting-ip");
|
|
31
|
+
if (!secret || !ip || !isIP(ip)) return {};
|
|
32
|
+
return {
|
|
33
|
+
"X-Client-IP": ip,
|
|
34
|
+
"X-Relay-Auth": secret
|
|
35
|
+
};
|
|
36
|
+
}
|
|
23
37
|
//#endregion
|
|
24
|
-
export { relayHeaders };
|
|
38
|
+
export { relayHeaders, staffRelayHeaders };
|
package/dist/session-cookie.d.ts
CHANGED
|
@@ -29,6 +29,14 @@ export interface ShopBoundCookieConfig {
|
|
|
29
29
|
path: "/";
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Storefronts on `<handle>.adorly.mn` run merchant script, and `adorly.mn` is
|
|
34
|
+
* not a public suffix, so any storefront can set a same-named cookie for the
|
|
35
|
+
* parent domain and fix a buyer (or a staff app's user) into the attacker's
|
|
36
|
+
* session. Only the host itself can set a `__Host-` cookie. The prefix
|
|
37
|
+
* requires `Secure`, so plain-http dev keeps the bare name.
|
|
38
|
+
*/
|
|
39
|
+
export declare function hostOnlyCookieName(base: string, secure?: boolean): string;
|
|
32
40
|
export declare function createShopBoundCookieConfig(opts: {
|
|
33
41
|
name: string;
|
|
34
42
|
password: string;
|
package/dist/session-cookie.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Storefronts on `<handle>.adorly.mn` run merchant script, and `adorly.mn` is
|
|
4
4
|
* not a public suffix, so any storefront can set a same-named cookie for the
|
|
5
|
-
* parent domain and fix a buyer
|
|
6
|
-
* itself can set a `__Host-` cookie. The prefix
|
|
7
|
-
* plain-http dev keeps the bare name.
|
|
5
|
+
* parent domain and fix a buyer (or a staff app's user) into the attacker's
|
|
6
|
+
* session. Only the host itself can set a `__Host-` cookie. The prefix
|
|
7
|
+
* requires `Secure`, so plain-http dev keeps the bare name.
|
|
8
8
|
*/
|
|
9
|
-
function hostOnlyCookieName(base, secure) {
|
|
9
|
+
function hostOnlyCookieName(base, secure = process.env.NODE_ENV === "production") {
|
|
10
10
|
return secure ? `__Host-${base}` : base;
|
|
11
11
|
}
|
|
12
12
|
function createShopBoundCookieConfig(opts) {
|
|
@@ -36,4 +36,4 @@ function validateShopBinding(payload, expectedShopHandle) {
|
|
|
36
36
|
return payload;
|
|
37
37
|
}
|
|
38
38
|
//#endregion
|
|
39
|
-
export { createShopBoundCookieConfig, validateShopBinding };
|
|
39
|
+
export { createShopBoundCookieConfig, hostOnlyCookieName, validateShopBinding };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shop-on/customer-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"license": "SEE LICENSE IN dist/LICENSE.md",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"./graphql": "./dist/graphql.js",
|
|
12
12
|
"./handoff": "./dist/handoff.js",
|
|
13
13
|
"./handoff-state": "./dist/handoff-state.js",
|
|
14
|
+
"./internal-api": "./dist/internal-api.js",
|
|
14
15
|
"./lease": "./dist/lease.js",
|
|
15
16
|
"./oauth": "./dist/oauth.js",
|
|
16
17
|
"./relay": "./dist/relay.js",
|