@thirdweb-dev/service-utils 0.0.0-dev-7899994-20230714075259 → 0.0.0-dev-88578bb-20230714081731

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-294e111f.esm.js +252 -0
  24. package/dist/index-3060948e.cjs.prod.js +254 -0
  25. package/dist/index-fcf69a55.cjs.dev.js +254 -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,254 @@
1
+ 'use strict';
2
+
3
+ async function fetchKeyMetadataFromApi(clientId, config) {
4
+ const {
5
+ apiUrl,
6
+ serviceScope,
7
+ serviceApiKey
8
+ } = config;
9
+ const url = new URL(`${apiUrl}/v1/keys/use`);
10
+ url.searchParams.set("clientId", clientId);
11
+ url.searchParams.set("scope", serviceScope);
12
+ const response = await fetch(url, {
13
+ method: "GET",
14
+ headers: {
15
+ "x-service-api-key": serviceApiKey,
16
+ "content-type": "application/json"
17
+ }
18
+ });
19
+ if (!response.ok) {
20
+ throw new Error(`Error fetching key metadata from API: ${response.statusText}`);
21
+ }
22
+ return await response.json();
23
+ }
24
+
25
+ function authorizeClient(authOptions, apiKeyMeta) {
26
+ const {
27
+ origin,
28
+ secretKeyHash: providedSecretHash
29
+ } = authOptions;
30
+ const {
31
+ domains,
32
+ secretHash
33
+ } = apiKeyMeta;
34
+ if (providedSecretHash) {
35
+ if (secretHash !== providedSecretHash) {
36
+ return {
37
+ authorized: false,
38
+ errorMessage: "The secret is invalid.",
39
+ errorCode: "SECRET_INVALID",
40
+ status: 401
41
+ };
42
+ }
43
+ return {
44
+ authorized: true,
45
+ apiKeyMeta
46
+ };
47
+ }
48
+
49
+ // validate domains
50
+ if (origin) {
51
+ if (
52
+ // find matching domain, or if all domains allowed
53
+ domains.find(d => {
54
+ if (d === "*") {
55
+ return true;
56
+ }
57
+
58
+ // If the allowedDomain has a wildcard,
59
+ // we'll check that the ending of our domain matches the wildcard
60
+ if (d.startsWith("*.")) {
61
+ const domainRoot = d.slice(2);
62
+ return origin.endsWith(domainRoot);
63
+ }
64
+
65
+ // If there's no wildcard, we'll check for an exact match
66
+ return d === origin;
67
+ })) {
68
+ return {
69
+ authorized: true,
70
+ apiKeyMeta
71
+ };
72
+ }
73
+ return {
74
+ authorized: false,
75
+ errorMessage: "The origin is not authorized for this key.",
76
+ errorCode: "ORIGIN_UNAUTHORIZED",
77
+ status: 401
78
+ };
79
+ }
80
+
81
+ // FIXME: validate bundle id
82
+ return {
83
+ authorized: false,
84
+ errorMessage: "The keys are invalid.",
85
+ errorCode: "UNAUTHORIZED",
86
+ status: 401
87
+ };
88
+ }
89
+
90
+ function authorizeService(apikeyMetadata, serviceConfig, authorizationPayload) {
91
+ const {
92
+ services
93
+ } = apikeyMetadata;
94
+ // const { serviceTargetAddresses, serviceAction } = validations;
95
+
96
+ // validate services
97
+ const service = services.find(srv => srv.name === serviceConfig.serviceScope);
98
+ if (!service) {
99
+ return {
100
+ authorized: false,
101
+ errorMessage: `The service "${serviceConfig.serviceScope}" is not authorized for this key.`,
102
+ errorCode: "SERVICE_UNAUTHORIZED",
103
+ status: 403
104
+ };
105
+ }
106
+
107
+ // validate service actions
108
+ if (serviceConfig.serviceAction) {
109
+ const isActionAllowed = service.actions.includes(serviceConfig.serviceAction);
110
+ if (!isActionAllowed) {
111
+ return {
112
+ authorized: false,
113
+ errorMessage: `The service "${serviceConfig.serviceScope}" action "${serviceConfig.serviceAction}" is not authorized for this key.`,
114
+ errorCode: "SERVICE_ACTION_UNAUTHORIZED",
115
+ status: 403
116
+ };
117
+ }
118
+ }
119
+
120
+ // validate service target addresses
121
+ // the service has to pass in the target address for this to be validated
122
+ if (authorizationPayload?.targetAddress) {
123
+ const isTargetAddressAllowed = service.targetAddresses.includes(authorizationPayload.targetAddress);
124
+ if (!isTargetAddressAllowed) {
125
+ return {
126
+ authorized: false,
127
+ errorMessage: `The service "${serviceConfig.serviceScope}" target address "${authorizationPayload.targetAddress}" is not authorized for this key.`,
128
+ errorCode: "SERVICE_TARGET_ADDRESS_UNAUTHORIZED",
129
+ status: 403
130
+ };
131
+ }
132
+ }
133
+ return {
134
+ authorized: true,
135
+ apiKeyMeta: apikeyMetadata
136
+ };
137
+ }
138
+
139
+ async function authorize(authData, serviceConfig, cacheOptions) {
140
+ // if we don't have a client id at this point we can't authorize
141
+ if (!authData.clientId) {
142
+ return {
143
+ authorized: false,
144
+ status: 401,
145
+ errorMessage: "Missing clientId or secretKey.",
146
+ errorCode: "MISSING_KEY"
147
+ };
148
+ }
149
+ let apiKeyMeta = null;
150
+ // if we have cache options we want to check the cache first
151
+ if (cacheOptions) {
152
+ try {
153
+ const cachedKey = await cacheOptions.get(authData.clientId);
154
+ if (cachedKey) {
155
+ const parsed = JSON.parse(cachedKey);
156
+ if ("updatedAt" in parsed) {
157
+ // we want to compare the updatedAt time to the current time
158
+ // if the difference is greater than the cacheTtl we want to ignore the cached data
159
+ const now = Date.now();
160
+ const diff = now - parsed.updatedAt;
161
+ const cacheTtl = cacheOptions.cacheTtlSeconds * 1000;
162
+ // only if the diff is less than the cacheTtl do we want to use the cached key
163
+ if (diff < cacheTtl * 1000) {
164
+ apiKeyMeta = parsed.apiKeyMeta;
165
+ }
166
+ } else {
167
+ apiKeyMeta = parsed;
168
+ }
169
+ }
170
+ } catch (err) {
171
+ // ignore errors, proceed as if not in cache
172
+ }
173
+ }
174
+
175
+ // if we don't have a cached key, fetch from the API
176
+ if (!apiKeyMeta) {
177
+ try {
178
+ const {
179
+ data,
180
+ error
181
+ } = await fetchKeyMetadataFromApi(authData.clientId, serviceConfig);
182
+ if (error) {
183
+ return {
184
+ authorized: false,
185
+ errorCode: error.code,
186
+ errorMessage: error.message,
187
+ status: error.statusCode
188
+ };
189
+ } else if (!data) {
190
+ return {
191
+ authorized: false,
192
+ errorCode: "NO_KEY",
193
+ errorMessage: "No error but also no key returned.",
194
+ status: 500
195
+ };
196
+ }
197
+ // if we have a key for sure then assign it
198
+ apiKeyMeta = data;
199
+
200
+ // cache the retrieved key if we have cache options
201
+ if (cacheOptions) {
202
+ // we await this always because it can be a promise or not
203
+ await cacheOptions.put(authData.clientId, data);
204
+ }
205
+ } catch (err) {
206
+ console.warn("failed to fetch key metadata from api", err);
207
+ return {
208
+ authorized: false,
209
+ status: 500,
210
+ errorMessage: "Failed to fetch key metadata.",
211
+ errorCode: "FAILED_TO_FETCH_KEY"
212
+ };
213
+ }
214
+ }
215
+ if (!apiKeyMeta) {
216
+ return {
217
+ authorized: false,
218
+ status: 401,
219
+ errorMessage: "Key is invalid.",
220
+ errorCode: "INVALID_KEY"
221
+ };
222
+ }
223
+ // now we can validate the key itself
224
+ const clientAuth = authorizeClient(authData, apiKeyMeta);
225
+ if (!clientAuth.authorized) {
226
+ return {
227
+ errorCode: clientAuth.errorCode,
228
+ authorized: false,
229
+ status: 401,
230
+ errorMessage: clientAuth.errorMessage
231
+ };
232
+ }
233
+
234
+ // if we've made it this far we need to check service specific authorization
235
+ const serviceAuth = authorizeService(apiKeyMeta, serviceConfig, {
236
+ targetAddress: authData.targetAddress
237
+ });
238
+ if (!serviceAuth.authorized) {
239
+ return {
240
+ errorCode: serviceAuth.errorCode,
241
+ authorized: false,
242
+ status: 403,
243
+ errorMessage: serviceAuth.errorMessage
244
+ };
245
+ }
246
+
247
+ // if we reach this point we are authorized!
248
+ return {
249
+ authorized: true,
250
+ apiKeyMeta
251
+ };
252
+ }
253
+
254
+ exports.authorize = authorize;
@@ -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-fcf69a55.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-3060948e.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;