@thirdweb-dev/service-utils 0.0.0-dev-7899994-20230714075259 → 0.0.0-dev-1d8a47a-20230714075515

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.
Files changed (41) hide show
  1. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.d.ts +2 -0
  2. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.d.ts.map +1 -0
  3. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.dev.js +115 -0
  4. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.js +7 -0
  5. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.prod.js +115 -0
  6. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.esm.js +105 -0
  7. package/dist/declarations/src/cf-worker/index.d.ts +18 -0
  8. package/dist/declarations/src/cf-worker/index.d.ts.map +1 -0
  9. package/dist/declarations/src/core/api.d.ts +31 -0
  10. package/dist/declarations/src/core/api.d.ts.map +1 -0
  11. package/dist/declarations/src/core/authorize/index.d.ts +18 -0
  12. package/dist/declarations/src/core/authorize/index.d.ts.map +1 -0
  13. package/dist/declarations/src/core/authorize/types.d.ts +11 -0
  14. package/dist/declarations/src/core/authorize/types.d.ts.map +1 -0
  15. package/dist/declarations/src/core/services.d.ts +101 -0
  16. package/dist/declarations/src/core/services.d.ts.map +1 -0
  17. package/dist/declarations/src/core/types.d.ts +5 -0
  18. package/dist/declarations/src/core/types.d.ts.map +1 -0
  19. package/dist/declarations/src/index.d.ts +2 -0
  20. package/dist/declarations/src/index.d.ts.map +1 -0
  21. package/dist/declarations/src/node/index.d.ts +16 -0
  22. package/dist/declarations/src/node/index.d.ts.map +1 -0
  23. package/dist/index-20c60154.cjs.prod.js +254 -0
  24. package/dist/index-781b85e1.cjs.dev.js +254 -0
  25. package/dist/index-9343e4ac.esm.js +252 -0
  26. package/dist/services-86283509.esm.js +44 -0
  27. package/dist/services-9e185105.cjs.prod.js +49 -0
  28. package/dist/services-a3f36057.cjs.dev.js +49 -0
  29. package/dist/thirdweb-dev-service-utils.cjs.d.ts +2 -0
  30. package/dist/thirdweb-dev-service-utils.cjs.d.ts.map +1 -0
  31. package/dist/thirdweb-dev-service-utils.cjs.dev.js +12 -0
  32. package/dist/thirdweb-dev-service-utils.cjs.js +7 -0
  33. package/dist/thirdweb-dev-service-utils.cjs.prod.js +12 -0
  34. package/dist/thirdweb-dev-service-utils.esm.js +1 -0
  35. package/node/dist/thirdweb-dev-service-utils-node.cjs.d.ts +2 -0
  36. package/node/dist/thirdweb-dev-service-utils-node.cjs.d.ts.map +1 -0
  37. package/node/dist/thirdweb-dev-service-utils-node.cjs.dev.js +113 -0
  38. package/node/dist/thirdweb-dev-service-utils-node.cjs.js +7 -0
  39. package/node/dist/thirdweb-dev-service-utils-node.cjs.prod.js +113 -0
  40. package/node/dist/thirdweb-dev-service-utils-node.esm.js +102 -0
  41. package/package.json +1 -1
@@ -0,0 +1,252 @@
1
+ async function fetchKeyMetadataFromApi(clientId, config) {
2
+ const {
3
+ apiUrl,
4
+ serviceScope,
5
+ serviceApiKey
6
+ } = config;
7
+ const url = new URL(`${apiUrl}/api/v1/keys`);
8
+ url.searchParams.set("clientId", clientId);
9
+ url.searchParams.set("scope", serviceScope);
10
+ const response = await fetch(url, {
11
+ method: "GET",
12
+ headers: {
13
+ "x-service-api-key": serviceApiKey,
14
+ "content-type": "application/json"
15
+ }
16
+ });
17
+ if (!response.ok) {
18
+ throw new Error(`Error fetching key metadata from API: ${response.statusText}`);
19
+ }
20
+ return await response.json();
21
+ }
22
+
23
+ function authorizeClient(authOptions, apiKeyMeta) {
24
+ const {
25
+ origin,
26
+ secretKeyHash: providedSecretHash
27
+ } = authOptions;
28
+ const {
29
+ domains,
30
+ secretHash
31
+ } = apiKeyMeta;
32
+ if (providedSecretHash) {
33
+ if (secretHash !== providedSecretHash) {
34
+ return {
35
+ authorized: false,
36
+ errorMessage: "The secret is invalid.",
37
+ errorCode: "SECRET_INVALID",
38
+ status: 401
39
+ };
40
+ }
41
+ return {
42
+ authorized: true,
43
+ apiKeyMeta
44
+ };
45
+ }
46
+
47
+ // validate domains
48
+ if (origin) {
49
+ if (
50
+ // find matching domain, or if all domains allowed
51
+ domains.find(d => {
52
+ if (d === "*") {
53
+ return true;
54
+ }
55
+
56
+ // If the allowedDomain has a wildcard,
57
+ // we'll check that the ending of our domain matches the wildcard
58
+ if (d.startsWith("*.")) {
59
+ const domainRoot = d.slice(2);
60
+ return origin.endsWith(domainRoot);
61
+ }
62
+
63
+ // If there's no wildcard, we'll check for an exact match
64
+ return d === origin;
65
+ })) {
66
+ return {
67
+ authorized: true,
68
+ apiKeyMeta
69
+ };
70
+ }
71
+ return {
72
+ authorized: false,
73
+ errorMessage: "The origin is not authorized for this key.",
74
+ errorCode: "ORIGIN_UNAUTHORIZED",
75
+ status: 401
76
+ };
77
+ }
78
+
79
+ // FIXME: validate bundle id
80
+ return {
81
+ authorized: false,
82
+ errorMessage: "The keys are invalid.",
83
+ errorCode: "UNAUTHORIZED",
84
+ status: 401
85
+ };
86
+ }
87
+
88
+ function authorizeService(apikeyMetadata, serviceConfig, authorizationPayload) {
89
+ const {
90
+ services
91
+ } = apikeyMetadata;
92
+ // const { serviceTargetAddresses, serviceAction } = validations;
93
+
94
+ // validate services
95
+ const service = services.find(srv => srv.name === serviceConfig.serviceScope);
96
+ if (!service) {
97
+ return {
98
+ authorized: false,
99
+ errorMessage: `The service "${serviceConfig.serviceScope}" is not authorized for this key.`,
100
+ errorCode: "SERVICE_UNAUTHORIZED",
101
+ status: 403
102
+ };
103
+ }
104
+
105
+ // validate service actions
106
+ if (serviceConfig.serviceAction) {
107
+ const isActionAllowed = service.actions.includes(serviceConfig.serviceAction);
108
+ if (!isActionAllowed) {
109
+ return {
110
+ authorized: false,
111
+ errorMessage: `The service "${serviceConfig.serviceScope}" action "${serviceConfig.serviceAction}" is not authorized for this key.`,
112
+ errorCode: "SERVICE_ACTION_UNAUTHORIZED",
113
+ status: 403
114
+ };
115
+ }
116
+ }
117
+
118
+ // validate service target addresses
119
+ // the service has to pass in the target address for this to be validated
120
+ if (authorizationPayload?.targetAddress) {
121
+ const isTargetAddressAllowed = service.targetAddresses.includes(authorizationPayload.targetAddress);
122
+ if (!isTargetAddressAllowed) {
123
+ return {
124
+ authorized: false,
125
+ errorMessage: `The service "${serviceConfig.serviceScope}" target address "${authorizationPayload.targetAddress}" is not authorized for this key.`,
126
+ errorCode: "SERVICE_TARGET_ADDRESS_UNAUTHORIZED",
127
+ status: 403
128
+ };
129
+ }
130
+ }
131
+ return {
132
+ authorized: true,
133
+ apiKeyMeta: apikeyMetadata
134
+ };
135
+ }
136
+
137
+ async function authorize(authData, serviceConfig, cacheOptions) {
138
+ // if we don't have a client id at this point we can't authorize
139
+ if (!authData.clientId) {
140
+ return {
141
+ authorized: false,
142
+ status: 401,
143
+ errorMessage: "Missing clientId or secretKey.",
144
+ errorCode: "MISSING_KEY"
145
+ };
146
+ }
147
+ let apiKeyMeta = null;
148
+ // if we have cache options we want to check the cache first
149
+ if (cacheOptions) {
150
+ try {
151
+ const cachedKey = await cacheOptions.get(authData.clientId);
152
+ if (cachedKey) {
153
+ const parsed = JSON.parse(cachedKey);
154
+ if ("updatedAt" in parsed) {
155
+ // we want to compare the updatedAt time to the current time
156
+ // if the difference is greater than the cacheTtl we want to ignore the cached data
157
+ const now = Date.now();
158
+ const diff = now - parsed.updatedAt;
159
+ const cacheTtl = cacheOptions.cacheTtlSeconds * 1000;
160
+ // only if the diff is less than the cacheTtl do we want to use the cached key
161
+ if (diff < cacheTtl * 1000) {
162
+ apiKeyMeta = parsed.apiKeyMeta;
163
+ }
164
+ } else {
165
+ apiKeyMeta = parsed;
166
+ }
167
+ }
168
+ } catch (err) {
169
+ // ignore errors, proceed as if not in cache
170
+ }
171
+ }
172
+
173
+ // if we don't have a cached key, fetch from the API
174
+ if (!apiKeyMeta) {
175
+ try {
176
+ const {
177
+ data,
178
+ error
179
+ } = await fetchKeyMetadataFromApi(authData.clientId, serviceConfig);
180
+ if (error) {
181
+ return {
182
+ authorized: false,
183
+ errorCode: error.code,
184
+ errorMessage: error.message,
185
+ status: error.statusCode
186
+ };
187
+ } else if (!data) {
188
+ return {
189
+ authorized: false,
190
+ errorCode: "NO_KEY",
191
+ errorMessage: "No error but also no key returned.",
192
+ status: 500
193
+ };
194
+ }
195
+ // if we have a key for sure then assign it
196
+ apiKeyMeta = data;
197
+
198
+ // cache the retrieved key if we have cache options
199
+ if (cacheOptions) {
200
+ // we await this always because it can be a promise or not
201
+ await cacheOptions.put(authData.clientId, data);
202
+ }
203
+ } catch (err) {
204
+ console.warn("failed to fetch key metadata from api", err);
205
+ return {
206
+ authorized: false,
207
+ status: 500,
208
+ errorMessage: "Failed to fetch key metadata.",
209
+ errorCode: "FAILED_TO_FETCH_KEY"
210
+ };
211
+ }
212
+ }
213
+ if (!apiKeyMeta) {
214
+ return {
215
+ authorized: false,
216
+ status: 401,
217
+ errorMessage: "Key is invalid.",
218
+ errorCode: "INVALID_KEY"
219
+ };
220
+ }
221
+ // now we can validate the key itself
222
+ const clientAuth = authorizeClient(authData, apiKeyMeta);
223
+ if (!clientAuth.authorized) {
224
+ return {
225
+ errorCode: clientAuth.errorCode,
226
+ authorized: false,
227
+ status: 401,
228
+ errorMessage: clientAuth.errorMessage
229
+ };
230
+ }
231
+
232
+ // if we've made it this far we need to check service specific authorization
233
+ const serviceAuth = authorizeService(apiKeyMeta, serviceConfig, {
234
+ targetAddress: authData.targetAddress
235
+ });
236
+ if (!serviceAuth.authorized) {
237
+ return {
238
+ errorCode: serviceAuth.errorCode,
239
+ authorized: false,
240
+ status: 403,
241
+ errorMessage: serviceAuth.errorMessage
242
+ };
243
+ }
244
+
245
+ // if we reach this point we are authorized!
246
+ return {
247
+ authorized: true,
248
+ apiKeyMeta
249
+ };
250
+ }
251
+
252
+ export { authorize as a };
@@ -0,0 +1,44 @@
1
+ const SERVICE_DEFINITIONS = {
2
+ storage: {
3
+ name: "storage",
4
+ title: "Storage",
5
+ description: "IPFS Upload and Download",
6
+ actions: [{
7
+ name: "read",
8
+ title: "Download",
9
+ description: "Download a file from Storage"
10
+ }, {
11
+ name: "write",
12
+ title: "Upload",
13
+ description: "Upload a file to Storage"
14
+ }]
15
+ },
16
+ rpc: {
17
+ name: "rpc",
18
+ title: "RPC",
19
+ description: "Accelerated RPC Edge",
20
+ // all actions allowed
21
+ actions: []
22
+ },
23
+ bundler: {
24
+ name: "bundler",
25
+ title: "Smart Wallets",
26
+ description: "Bundler & Paymaster services",
27
+ // all actions allowed
28
+ actions: []
29
+ },
30
+ relayer: {
31
+ name: "relayer",
32
+ title: "Gasless Relayer",
33
+ description: "Enable gasless transactions",
34
+ // all actions allowed
35
+ actions: []
36
+ }
37
+ };
38
+ const SERVICE_NAMES = Object.keys(SERVICE_DEFINITIONS);
39
+ const SERVICES = Object.values(SERVICE_DEFINITIONS);
40
+ function getServiceByName(name) {
41
+ return SERVICE_DEFINITIONS[name];
42
+ }
43
+
44
+ export { SERVICE_DEFINITIONS as S, SERVICE_NAMES as a, SERVICES as b, getServiceByName as g };
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const SERVICE_DEFINITIONS = {
4
+ storage: {
5
+ name: "storage",
6
+ title: "Storage",
7
+ description: "IPFS Upload and Download",
8
+ actions: [{
9
+ name: "read",
10
+ title: "Download",
11
+ description: "Download a file from Storage"
12
+ }, {
13
+ name: "write",
14
+ title: "Upload",
15
+ description: "Upload a file to Storage"
16
+ }]
17
+ },
18
+ rpc: {
19
+ name: "rpc",
20
+ title: "RPC",
21
+ description: "Accelerated RPC Edge",
22
+ // all actions allowed
23
+ actions: []
24
+ },
25
+ bundler: {
26
+ name: "bundler",
27
+ title: "Smart Wallets",
28
+ description: "Bundler & Paymaster services",
29
+ // all actions allowed
30
+ actions: []
31
+ },
32
+ relayer: {
33
+ name: "relayer",
34
+ title: "Gasless Relayer",
35
+ description: "Enable gasless transactions",
36
+ // all actions allowed
37
+ actions: []
38
+ }
39
+ };
40
+ const SERVICE_NAMES = Object.keys(SERVICE_DEFINITIONS);
41
+ const SERVICES = Object.values(SERVICE_DEFINITIONS);
42
+ function getServiceByName(name) {
43
+ return SERVICE_DEFINITIONS[name];
44
+ }
45
+
46
+ exports.SERVICES = SERVICES;
47
+ exports.SERVICE_DEFINITIONS = SERVICE_DEFINITIONS;
48
+ exports.SERVICE_NAMES = SERVICE_NAMES;
49
+ exports.getServiceByName = getServiceByName;
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const SERVICE_DEFINITIONS = {
4
+ storage: {
5
+ name: "storage",
6
+ title: "Storage",
7
+ description: "IPFS Upload and Download",
8
+ actions: [{
9
+ name: "read",
10
+ title: "Download",
11
+ description: "Download a file from Storage"
12
+ }, {
13
+ name: "write",
14
+ title: "Upload",
15
+ description: "Upload a file to Storage"
16
+ }]
17
+ },
18
+ rpc: {
19
+ name: "rpc",
20
+ title: "RPC",
21
+ description: "Accelerated RPC Edge",
22
+ // all actions allowed
23
+ actions: []
24
+ },
25
+ bundler: {
26
+ name: "bundler",
27
+ title: "Smart Wallets",
28
+ description: "Bundler & Paymaster services",
29
+ // all actions allowed
30
+ actions: []
31
+ },
32
+ relayer: {
33
+ name: "relayer",
34
+ title: "Gasless Relayer",
35
+ description: "Enable gasless transactions",
36
+ // all actions allowed
37
+ actions: []
38
+ }
39
+ };
40
+ const SERVICE_NAMES = Object.keys(SERVICE_DEFINITIONS);
41
+ const SERVICES = Object.values(SERVICE_DEFINITIONS);
42
+ function getServiceByName(name) {
43
+ return SERVICE_DEFINITIONS[name];
44
+ }
45
+
46
+ exports.SERVICES = SERVICES;
47
+ exports.SERVICE_DEFINITIONS = SERVICE_DEFINITIONS;
48
+ exports.SERVICE_NAMES = SERVICE_NAMES;
49
+ exports.getServiceByName = getServiceByName;
@@ -0,0 +1,2 @@
1
+ export * from "./declarations/src/index";
2
+ //# sourceMappingURL=thirdweb-dev-service-utils.cjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thirdweb-dev-service-utils.cjs.d.ts","sourceRoot":"","sources":["./declarations/src/index.d.ts"],"names":[],"mappings":"AAAA"}
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var services = require('./services-a3f36057.cjs.dev.js');
6
+
7
+
8
+
9
+ exports.SERVICES = services.SERVICES;
10
+ exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
11
+ exports.SERVICE_NAMES = services.SERVICE_NAMES;
12
+ exports.getServiceByName = services.getServiceByName;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === "production") {
4
+ module.exports = require("./thirdweb-dev-service-utils.cjs.prod.js");
5
+ } else {
6
+ module.exports = require("./thirdweb-dev-service-utils.cjs.dev.js");
7
+ }
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var services = require('./services-9e185105.cjs.prod.js');
6
+
7
+
8
+
9
+ exports.SERVICES = services.SERVICES;
10
+ exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
11
+ exports.SERVICE_NAMES = services.SERVICE_NAMES;
12
+ exports.getServiceByName = services.getServiceByName;
@@ -0,0 +1 @@
1
+ export { b as SERVICES, S as SERVICE_DEFINITIONS, a as SERVICE_NAMES, g as getServiceByName } from './services-86283509.esm.js';
@@ -0,0 +1,2 @@
1
+ export * from "../../dist/declarations/src/node/index";
2
+ //# sourceMappingURL=thirdweb-dev-service-utils-node.cjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thirdweb-dev-service-utils-node.cjs.d.ts","sourceRoot":"","sources":["../../dist/declarations/src/node/index.d.ts"],"names":[],"mappings":"AAAA"}
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var node_crypto = require('node:crypto');
6
+ var index = require('../../dist/index-781b85e1.cjs.dev.js');
7
+ var services = require('../../dist/services-a3f36057.cjs.dev.js');
8
+
9
+ async function authorizeNode(authInput, serviceConfig) {
10
+ let authData;
11
+ try {
12
+ authData = extractAuthorizationData(authInput);
13
+ } catch (e) {
14
+ if (e instanceof Error && e.message === "KEY_CONFLICT") {
15
+ return {
16
+ authorized: false,
17
+ status: 400,
18
+ errorMessage: "Please pass either a client id or a secret key.",
19
+ errorCode: "KEY_CONFLICT"
20
+ };
21
+ }
22
+ return {
23
+ authorized: false,
24
+ status: 500,
25
+ errorMessage: "Internal Server Error",
26
+ errorCode: "INTERNAL_SERVER_ERROR"
27
+ };
28
+ }
29
+ return await index.authorize(authData, serviceConfig);
30
+ }
31
+ function getHeader(headers, headerName) {
32
+ const header = headers[headerName];
33
+ if (Array.isArray(header)) {
34
+ return header[0];
35
+ }
36
+ return header ?? null;
37
+ }
38
+ function extractAuthorizationData(authInput) {
39
+ if (!authInput.req.url) {
40
+ throw new Error("no req.url in authInput.req");
41
+ }
42
+ const requestUrl = new URL(authInput.req.url, authInput.req.headers.host);
43
+ const headers = authInput.req.headers;
44
+ const secretKey = getHeader(headers, "x-secret-key");
45
+ // prefer clientId that is explicitly passed in
46
+ let clientId = authInput.clientId ?? null;
47
+ if (!clientId) {
48
+ // next preference is clientId from header
49
+ clientId = getHeader(headers, "x-client-id");
50
+ }
51
+
52
+ // next preference is search param
53
+ if (!clientId) {
54
+ clientId = requestUrl.searchParams.get("clientId");
55
+ }
56
+ // bundle id from header is first preference
57
+ let bundleId = getHeader(headers, "x-bundle-id");
58
+
59
+ // next preference is search param
60
+ if (!bundleId) {
61
+ bundleId = requestUrl.searchParams.get("bundleId");
62
+ }
63
+ let origin = getHeader(headers, "origin");
64
+ // if origin header is not available we'll fall back to referrer;
65
+ if (!origin) {
66
+ origin = getHeader(headers, "referer");
67
+ }
68
+ // if we have an origin at this point, normalize it
69
+ if (origin) {
70
+ try {
71
+ origin = new URL(origin).hostname;
72
+ } catch (e) {
73
+ console.warn("failed to parse origin", origin, e);
74
+ }
75
+ }
76
+
77
+ // handle if we a secret key is passed in the headers
78
+ let secretKeyHash = null;
79
+ if (secretKey) {
80
+ // hash the secret key
81
+ secretKeyHash = hashSecretKey(secretKey);
82
+ // derive the client id from the secret key hash
83
+ const derivedClientId = deriveClientIdFromSecretKeyHash(secretKeyHash);
84
+ // if we already have a client id passed in we need to make sure they match
85
+ if (clientId && clientId !== derivedClientId) {
86
+ throw new Error("KEY_CONFLICT");
87
+ }
88
+ // otherwise set the client id to the derived client id (client id based off of secret key)
89
+ clientId = derivedClientId;
90
+ }
91
+ return {
92
+ secretKeyHash,
93
+ secretKey,
94
+ clientId,
95
+ origin,
96
+ bundleId
97
+ };
98
+ }
99
+ function hashSecretKey(secretKey) {
100
+ return node_crypto.createHash("sha256").update(secretKey).digest("hex");
101
+ }
102
+ function deriveClientIdFromSecretKeyHash(secretKeyHash) {
103
+ return secretKeyHash.slice(0, 32);
104
+ }
105
+
106
+ exports.SERVICES = services.SERVICES;
107
+ exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
108
+ exports.SERVICE_NAMES = services.SERVICE_NAMES;
109
+ exports.getServiceByName = services.getServiceByName;
110
+ exports.authorizeNode = authorizeNode;
111
+ exports.deriveClientIdFromSecretKeyHash = deriveClientIdFromSecretKeyHash;
112
+ exports.extractAuthorizationData = extractAuthorizationData;
113
+ exports.hashSecretKey = hashSecretKey;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === "production") {
4
+ module.exports = require("./thirdweb-dev-service-utils-node.cjs.prod.js");
5
+ } else {
6
+ module.exports = require("./thirdweb-dev-service-utils-node.cjs.dev.js");
7
+ }
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var node_crypto = require('node:crypto');
6
+ var index = require('../../dist/index-20c60154.cjs.prod.js');
7
+ var services = require('../../dist/services-9e185105.cjs.prod.js');
8
+
9
+ async function authorizeNode(authInput, serviceConfig) {
10
+ let authData;
11
+ try {
12
+ authData = extractAuthorizationData(authInput);
13
+ } catch (e) {
14
+ if (e instanceof Error && e.message === "KEY_CONFLICT") {
15
+ return {
16
+ authorized: false,
17
+ status: 400,
18
+ errorMessage: "Please pass either a client id or a secret key.",
19
+ errorCode: "KEY_CONFLICT"
20
+ };
21
+ }
22
+ return {
23
+ authorized: false,
24
+ status: 500,
25
+ errorMessage: "Internal Server Error",
26
+ errorCode: "INTERNAL_SERVER_ERROR"
27
+ };
28
+ }
29
+ return await index.authorize(authData, serviceConfig);
30
+ }
31
+ function getHeader(headers, headerName) {
32
+ const header = headers[headerName];
33
+ if (Array.isArray(header)) {
34
+ return header[0];
35
+ }
36
+ return header ?? null;
37
+ }
38
+ function extractAuthorizationData(authInput) {
39
+ if (!authInput.req.url) {
40
+ throw new Error("no req.url in authInput.req");
41
+ }
42
+ const requestUrl = new URL(authInput.req.url, authInput.req.headers.host);
43
+ const headers = authInput.req.headers;
44
+ const secretKey = getHeader(headers, "x-secret-key");
45
+ // prefer clientId that is explicitly passed in
46
+ let clientId = authInput.clientId ?? null;
47
+ if (!clientId) {
48
+ // next preference is clientId from header
49
+ clientId = getHeader(headers, "x-client-id");
50
+ }
51
+
52
+ // next preference is search param
53
+ if (!clientId) {
54
+ clientId = requestUrl.searchParams.get("clientId");
55
+ }
56
+ // bundle id from header is first preference
57
+ let bundleId = getHeader(headers, "x-bundle-id");
58
+
59
+ // next preference is search param
60
+ if (!bundleId) {
61
+ bundleId = requestUrl.searchParams.get("bundleId");
62
+ }
63
+ let origin = getHeader(headers, "origin");
64
+ // if origin header is not available we'll fall back to referrer;
65
+ if (!origin) {
66
+ origin = getHeader(headers, "referer");
67
+ }
68
+ // if we have an origin at this point, normalize it
69
+ if (origin) {
70
+ try {
71
+ origin = new URL(origin).hostname;
72
+ } catch (e) {
73
+ console.warn("failed to parse origin", origin, e);
74
+ }
75
+ }
76
+
77
+ // handle if we a secret key is passed in the headers
78
+ let secretKeyHash = null;
79
+ if (secretKey) {
80
+ // hash the secret key
81
+ secretKeyHash = hashSecretKey(secretKey);
82
+ // derive the client id from the secret key hash
83
+ const derivedClientId = deriveClientIdFromSecretKeyHash(secretKeyHash);
84
+ // if we already have a client id passed in we need to make sure they match
85
+ if (clientId && clientId !== derivedClientId) {
86
+ throw new Error("KEY_CONFLICT");
87
+ }
88
+ // otherwise set the client id to the derived client id (client id based off of secret key)
89
+ clientId = derivedClientId;
90
+ }
91
+ return {
92
+ secretKeyHash,
93
+ secretKey,
94
+ clientId,
95
+ origin,
96
+ bundleId
97
+ };
98
+ }
99
+ function hashSecretKey(secretKey) {
100
+ return node_crypto.createHash("sha256").update(secretKey).digest("hex");
101
+ }
102
+ function deriveClientIdFromSecretKeyHash(secretKeyHash) {
103
+ return secretKeyHash.slice(0, 32);
104
+ }
105
+
106
+ exports.SERVICES = services.SERVICES;
107
+ exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
108
+ exports.SERVICE_NAMES = services.SERVICE_NAMES;
109
+ exports.getServiceByName = services.getServiceByName;
110
+ exports.authorizeNode = authorizeNode;
111
+ exports.deriveClientIdFromSecretKeyHash = deriveClientIdFromSecretKeyHash;
112
+ exports.extractAuthorizationData = extractAuthorizationData;
113
+ exports.hashSecretKey = hashSecretKey;