@oxyhq/core 12.11.1 → 13.2.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/README.md +36 -2
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/index.js +4 -13
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +0 -31
- package/dist/cjs/mixins/OxyServices.user.js +50 -44
- package/dist/cjs/server/index.js +9 -6
- package/dist/cjs/server/rateLimit.js +3 -0
- package/dist/cjs/server/securityHeaders.js +234 -0
- package/dist/cjs/session/accountDialogController.js +6 -8
- package/dist/cjs/utils/apiUtils.js +40 -10
- package/dist/cjs/utils/oauthPkce.js +1 -5
- package/dist/cjs/utils/officialOrigins.js +3 -73
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/index.js +3 -4
- package/dist/esm/mixins/OxyServices.deviceBoot.js +1 -32
- package/dist/esm/mixins/OxyServices.user.js +51 -45
- package/dist/esm/server/index.js +4 -1
- package/dist/esm/server/rateLimit.js +3 -0
- package/dist/esm/server/securityHeaders.js +224 -0
- package/dist/esm/session/accountDialogController.js +6 -8
- package/dist/esm/utils/apiUtils.js +39 -10
- package/dist/esm/utils/oauthPkce.js +0 -4
- package/dist/esm/utils/officialOrigins.js +3 -68
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/index.d.ts +5 -7
- package/dist/types/mixins/OxyServices.auth.d.ts +1 -12
- package/dist/types/mixins/OxyServices.deviceBoot.d.ts +1 -5
- package/dist/types/mixins/OxyServices.user.d.ts +27 -6
- package/dist/types/server/index.d.ts +3 -1
- package/dist/types/server/securityHeaders.d.ts +154 -0
- package/dist/types/session/accountDialogController.d.ts +9 -15
- package/dist/types/utils/apiUtils.d.ts +48 -6
- package/dist/types/utils/oauthPkce.d.ts +11 -7
- package/dist/types/utils/officialOrigins.d.ts +3 -13
- package/package.json +10 -5
- package/src/index.ts +9 -14
- package/src/mixins/OxyServices.auth.ts +6 -13
- package/src/mixins/OxyServices.deviceBoot.ts +0 -47
- package/src/mixins/OxyServices.user.ts +60 -49
- package/src/mixins/__tests__/commonsSignIn.test.ts +9 -2
- package/src/mixins/__tests__/followGraphPagination.test.ts +250 -0
- package/src/server/__tests__/securityHeaders.test.ts +244 -0
- package/src/server/index.ts +17 -8
- package/src/server/rateLimit.ts +3 -0
- package/src/server/securityHeaders.ts +304 -0
- package/src/session/__tests__/accountDialogController.test.ts +3 -5
- package/src/session/accountDialogController.ts +12 -18
- package/src/utils/__tests__/officialOrigins.test.ts +0 -57
- package/src/utils/apiUtils.ts +64 -15
- package/src/utils/oauthPkce.ts +11 -9
- package/src/utils/officialOrigins.ts +3 -70
- package/dist/cjs/session/hubSync.js +0 -55
- package/dist/esm/session/hubSync.js +0 -51
- package/dist/types/session/hubSync.d.ts +0 -20
- package/src/session/__tests__/hubSync.test.ts +0 -51
- package/src/session/hubSync.ts +0 -79
|
@@ -3,23 +3,49 @@
|
|
|
3
3
|
* Utility functions for common API patterns
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildQueryParams = buildQueryParams;
|
|
6
7
|
exports.buildSearchParams = buildSearchParams;
|
|
7
8
|
exports.buildUrl = buildUrl;
|
|
8
9
|
exports.buildPaginationParams = buildPaginationParams;
|
|
9
10
|
exports.safeJsonParse = safeJsonParse;
|
|
10
11
|
/**
|
|
11
|
-
* Build
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Build a plain query-parameter record from an object, stringifying values and
|
|
13
|
+
* dropping `undefined`/`null` entries.
|
|
14
|
+
*
|
|
15
|
+
* This is the shape `OxyServices.makeRequest` expects for a GET's `params`:
|
|
16
|
+
* `HttpService` inspects it with `Object.keys(...)` (both to decide whether to
|
|
17
|
+
* append a query string and to build the request's cache key), and
|
|
18
|
+
* `Object.keys(new URLSearchParams({ limit: '20' }))` is `[]` — a
|
|
19
|
+
* `URLSearchParams` exposes its entries through iterator methods, never as own
|
|
20
|
+
* enumerable properties. Passing one to `makeRequest` therefore silently drops
|
|
21
|
+
* the whole query string. Always hand `makeRequest` a plain record.
|
|
22
|
+
*
|
|
23
|
+
* Generic over the input object rather than taking `Record<string, unknown>`,
|
|
24
|
+
* because a TypeScript `interface` (`PaginationParams`, `FollowGraphParams`, …)
|
|
25
|
+
* has no implicit index signature and so is not assignable to that type.
|
|
14
26
|
*/
|
|
15
|
-
function
|
|
16
|
-
const
|
|
27
|
+
function buildQueryParams(params) {
|
|
28
|
+
const query = {};
|
|
29
|
+
// Widening the value to `unknown` is always sound; the default overload of
|
|
30
|
+
// `Object.entries` would otherwise infer `any` here.
|
|
17
31
|
for (const [key, value] of Object.entries(params)) {
|
|
18
32
|
if (value !== undefined && value !== null) {
|
|
19
|
-
|
|
33
|
+
query[key] = String(value);
|
|
20
34
|
}
|
|
21
35
|
}
|
|
22
|
-
return
|
|
36
|
+
return query;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build URL search parameters from an object.
|
|
40
|
+
*
|
|
41
|
+
* For building a URL string only — see {@link buildQueryParams} for the shape
|
|
42
|
+
* `makeRequest` needs.
|
|
43
|
+
*
|
|
44
|
+
* @param params Object with parameter key-value pairs
|
|
45
|
+
* @returns URLSearchParams instance
|
|
46
|
+
*/
|
|
47
|
+
function buildSearchParams(params) {
|
|
48
|
+
return new URLSearchParams(buildQueryParams(params));
|
|
23
49
|
}
|
|
24
50
|
/**
|
|
25
51
|
* Build URL with search parameters
|
|
@@ -35,12 +61,16 @@ function buildUrl(baseUrl, params) {
|
|
|
35
61
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
|
36
62
|
}
|
|
37
63
|
/**
|
|
38
|
-
* Build pagination
|
|
64
|
+
* Build pagination query parameters.
|
|
65
|
+
*
|
|
66
|
+
* Returns a plain record — NOT a `URLSearchParams` — because that is the only
|
|
67
|
+
* shape `makeRequest`/`HttpService` can read. See {@link buildQueryParams}.
|
|
68
|
+
*
|
|
39
69
|
* @param params Pagination parameters
|
|
40
|
-
* @returns
|
|
70
|
+
* @returns Query record with pagination
|
|
41
71
|
*/
|
|
42
72
|
function buildPaginationParams(params) {
|
|
43
|
-
return
|
|
73
|
+
return buildQueryParams(params);
|
|
44
74
|
}
|
|
45
75
|
/**
|
|
46
76
|
* Safe JSON parsing with error handling
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* React Native. No `require()`, so the ESM build stays bundler-clean.
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = exports.
|
|
20
|
+
exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.DEFAULT_OAUTH_SCOPE = exports.OXY_AUTHORIZE_URL = void 0;
|
|
21
21
|
exports.computeCodeChallenge = computeCodeChallenge;
|
|
22
22
|
exports.generatePkcePair = generatePkcePair;
|
|
23
23
|
exports.generateOAuthState = generateOAuthState;
|
|
@@ -159,10 +159,6 @@ exports.OXY_OAUTH_STATE_STORAGE_KEY = 'oxy_oauth_state';
|
|
|
159
159
|
exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = 'oxy_oauth_code_verifier';
|
|
160
160
|
/** `sessionStorage` key — the exact `redirect_uri` sent on the authorize request. */
|
|
161
161
|
exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = 'oxy.oauth_redirect_uri';
|
|
162
|
-
/** `sessionStorage` key — at most one silent OAuth attempt per navigation. */
|
|
163
|
-
exports.OXY_SILENT_OAUTH_ATTEMPTED_KEY = 'oxy.silent_oauth_attempted';
|
|
164
|
-
/** `sessionStorage` key — blocks further cross-origin auto-restore in this tab. */
|
|
165
|
-
exports.OXY_CROSS_ORIGIN_RESTORE_ATTEMPTED_KEY = 'oxy.cross_origin_restore_attempted';
|
|
166
162
|
/**
|
|
167
163
|
* `sessionStorage` key for the in-app path to return to after an authorize
|
|
168
164
|
* round trip. See {@link persistOAuthReturnPath}.
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Official first-party web origin allowlist — shared by
|
|
4
|
-
*
|
|
3
|
+
* Official first-party web origin allowlist — shared by OAuth redirect
|
|
4
|
+
* validation and the server-side trusted-origin checks.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.isAllowedDeviceJoinOrigin = void 0;
|
|
8
|
-
exports.buildIdpHubOrigin = buildIdpHubOrigin;
|
|
9
|
-
exports.isIdpHubOrigin = isIdpHubOrigin;
|
|
10
8
|
exports.isLoopbackOrigin = isLoopbackOrigin;
|
|
11
9
|
exports.isOfficialWebOrigin = isOfficialWebOrigin;
|
|
12
|
-
exports.normalizeOfficialReturnOrigin = normalizeOfficialReturnOrigin;
|
|
13
|
-
exports.parseHubSyncReturnUrl = parseHubSyncReturnUrl;
|
|
14
|
-
exports.buildHubSyncUrl = buildHubSyncUrl;
|
|
15
10
|
const authWebUrl_1 = require("./authWebUrl");
|
|
16
11
|
const registrableApex_1 = require("./registrableApex");
|
|
17
12
|
/** Official first-party registrable apexes (mirrors API trusted origins). */
|
|
@@ -27,30 +22,9 @@ const OFFICIAL_APEXES = new Set([
|
|
|
27
22
|
'moovo.now',
|
|
28
23
|
'mercaria.co',
|
|
29
24
|
]);
|
|
30
|
-
function buildIdpHubOrigin() {
|
|
31
|
-
return `https://auth.${authWebUrl_1.CENTRAL_IDP_APEX}`;
|
|
32
|
-
}
|
|
33
|
-
/** Whether the current web origin is the central IdP hub (`auth.oxy.so`). */
|
|
34
|
-
function isIdpHubOrigin() {
|
|
35
|
-
if (typeof globalThis === 'undefined') {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
const location = globalThis.location;
|
|
39
|
-
if (!location) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
try {
|
|
43
|
-
const { hostname } = new URL(location.href);
|
|
44
|
-
return hostname === `auth.${authWebUrl_1.CENTRAL_IDP_APEX}`;
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
25
|
/**
|
|
51
26
|
* Whether an origin is a loopback / local-dev origin (`localhost`, `127.0.0.1`,
|
|
52
|
-
* or `[::1]` on any port, http or https).
|
|
53
|
-
* hosted IdP for cross-origin session restore.
|
|
27
|
+
* or `[::1]` on any port, http or https).
|
|
54
28
|
*/
|
|
55
29
|
function isLoopbackOrigin(origin) {
|
|
56
30
|
try {
|
|
@@ -86,49 +60,5 @@ function isOfficialWebOrigin(origin) {
|
|
|
86
60
|
return false;
|
|
87
61
|
}
|
|
88
62
|
}
|
|
89
|
-
/** Normalize and validate a return URL against official origins. Returns origin only. */
|
|
90
|
-
function normalizeOfficialReturnOrigin(raw) {
|
|
91
|
-
try {
|
|
92
|
-
const parsed = new URL(raw);
|
|
93
|
-
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
if (!isOfficialWebOrigin(parsed.origin)) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
return parsed.origin;
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/** Validate a hub-sync return URL; returns the full normalized URL string. */
|
|
106
|
-
function parseHubSyncReturnUrl(raw) {
|
|
107
|
-
if (!raw) {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
try {
|
|
111
|
-
const parsed = new URL(raw);
|
|
112
|
-
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
if (!isOfficialWebOrigin(parsed.origin)) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
return parsed.toString();
|
|
119
|
-
}
|
|
120
|
-
catch {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
/** Build auth.oxy.so/sync redirect URL with a one-time hub ticket. */
|
|
125
|
-
function buildHubSyncUrl(ticket, returnUrl) {
|
|
126
|
-
const url = new URL('/sync', buildIdpHubOrigin());
|
|
127
|
-
url.searchParams.set('ticket', ticket);
|
|
128
|
-
if (returnUrl) {
|
|
129
|
-
url.searchParams.set('return', returnUrl);
|
|
130
|
-
}
|
|
131
|
-
return url.toString();
|
|
132
|
-
}
|
|
133
63
|
/** @deprecated Use {@link isOfficialWebOrigin}. */
|
|
134
64
|
exports.isAllowedDeviceJoinOrigin = isOfficialWebOrigin;
|