@thirdweb-dev/service-utils 0.4.38 → 0.4.39

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 (149) hide show
  1. package/dist/cjs/cf-worker/index.js +155 -0
  2. package/dist/cjs/cf-worker/index.js.map +1 -0
  3. package/dist/cjs/cf-worker/usage.js +55 -0
  4. package/dist/cjs/cf-worker/usage.js.map +1 -0
  5. package/dist/cjs/core/api.js +65 -0
  6. package/dist/cjs/core/api.js.map +1 -0
  7. package/dist/cjs/core/authorize/client.js +115 -0
  8. package/dist/cjs/core/authorize/client.js.map +1 -0
  9. package/dist/cjs/core/authorize/index.js +215 -0
  10. package/dist/cjs/core/authorize/index.js.map +1 -0
  11. package/dist/cjs/core/authorize/service.js +58 -0
  12. package/dist/cjs/core/authorize/service.js.map +1 -0
  13. package/dist/cjs/core/authorize/types.js +3 -0
  14. package/dist/cjs/core/authorize/types.js.map +1 -0
  15. package/dist/cjs/core/rateLimit/index.js +64 -0
  16. package/dist/cjs/core/rateLimit/index.js.map +1 -0
  17. package/dist/cjs/core/rateLimit/types.js +3 -0
  18. package/dist/cjs/core/rateLimit/types.js.map +1 -0
  19. package/dist/cjs/core/services.js +71 -0
  20. package/dist/cjs/core/services.js.map +1 -0
  21. package/dist/cjs/core/types.js +3 -0
  22. package/dist/cjs/core/types.js.map +1 -0
  23. package/dist/cjs/core/usage.js +93 -0
  24. package/dist/cjs/core/usage.js.map +1 -0
  25. package/dist/cjs/core/usageLimit/index.js +45 -0
  26. package/dist/cjs/core/usageLimit/index.js.map +1 -0
  27. package/dist/cjs/core/usageLimit/types.js +3 -0
  28. package/dist/cjs/core/usageLimit/types.js.map +1 -0
  29. package/dist/cjs/index.js +10 -0
  30. package/dist/cjs/index.js.map +1 -0
  31. package/dist/cjs/mocks.js +53 -0
  32. package/dist/cjs/mocks.js.map +1 -0
  33. package/dist/cjs/node/index.js +173 -0
  34. package/dist/cjs/node/index.js.map +1 -0
  35. package/dist/cjs/package.json +1 -0
  36. package/dist/esm/cf-worker/index.js +147 -0
  37. package/dist/esm/cf-worker/index.js.map +1 -0
  38. package/dist/esm/cf-worker/usage.js +54 -0
  39. package/dist/esm/cf-worker/usage.js.map +1 -0
  40. package/dist/esm/core/api.js +60 -0
  41. package/dist/esm/core/api.js.map +1 -0
  42. package/dist/esm/core/authorize/client.js +110 -0
  43. package/dist/esm/core/authorize/client.js.map +1 -0
  44. package/dist/esm/core/authorize/index.js +212 -0
  45. package/dist/esm/core/authorize/index.js.map +1 -0
  46. package/dist/esm/core/authorize/service.js +55 -0
  47. package/dist/esm/core/authorize/service.js.map +1 -0
  48. package/dist/esm/core/authorize/types.js +2 -0
  49. package/dist/esm/core/authorize/types.js.map +1 -0
  50. package/dist/esm/core/rateLimit/index.js +61 -0
  51. package/dist/esm/core/rateLimit/index.js.map +1 -0
  52. package/dist/esm/core/rateLimit/types.js +2 -0
  53. package/dist/esm/core/rateLimit/types.js.map +1 -0
  54. package/dist/esm/core/services.js +67 -0
  55. package/dist/esm/core/services.js.map +1 -0
  56. package/dist/esm/core/types.js +2 -0
  57. package/dist/esm/core/types.js.map +1 -0
  58. package/dist/esm/core/usage.js +90 -0
  59. package/dist/esm/core/usage.js.map +1 -0
  60. package/dist/esm/core/usageLimit/index.js +42 -0
  61. package/dist/esm/core/usageLimit/index.js.map +1 -0
  62. package/dist/esm/core/usageLimit/types.js +2 -0
  63. package/dist/esm/core/usageLimit/types.js.map +1 -0
  64. package/dist/esm/index.js +4 -0
  65. package/dist/esm/index.js.map +1 -0
  66. package/dist/esm/mocks.js +50 -0
  67. package/dist/esm/mocks.js.map +1 -0
  68. package/dist/esm/node/index.js +165 -0
  69. package/dist/esm/node/index.js.map +1 -0
  70. package/dist/esm/package.json +1 -0
  71. package/dist/{declarations/src → types}/cf-worker/index.d.ts +8 -8
  72. package/dist/types/cf-worker/index.d.ts.map +1 -0
  73. package/dist/{declarations/src → types}/cf-worker/usage.d.ts +3 -2
  74. package/dist/types/cf-worker/usage.d.ts.map +1 -0
  75. package/dist/{declarations/src → types}/core/api.d.ts +1 -1
  76. package/dist/types/core/api.d.ts.map +1 -0
  77. package/dist/{declarations/src → types}/core/authorize/client.d.ts +2 -2
  78. package/dist/types/core/authorize/client.d.ts.map +1 -0
  79. package/dist/{declarations/src → types}/core/authorize/index.d.ts +2 -2
  80. package/dist/types/core/authorize/index.d.ts.map +1 -0
  81. package/dist/{declarations/src → types}/core/authorize/service.d.ts +2 -2
  82. package/dist/types/core/authorize/service.d.ts.map +1 -0
  83. package/dist/{declarations/src → types}/core/authorize/types.d.ts +1 -1
  84. package/dist/types/core/authorize/types.d.ts.map +1 -0
  85. package/dist/{declarations/src → types}/core/rateLimit/index.d.ts +3 -3
  86. package/dist/types/core/rateLimit/index.d.ts.map +1 -0
  87. package/dist/types/core/rateLimit/types.d.ts.map +1 -0
  88. package/dist/types/core/services.d.ts.map +1 -0
  89. package/dist/types/core/types.d.ts.map +1 -0
  90. package/dist/{declarations/src → types}/core/usage.d.ts +2 -2
  91. package/dist/types/core/usage.d.ts.map +1 -0
  92. package/dist/types/core/usageLimit/index.d.ts +5 -0
  93. package/dist/types/core/usageLimit/index.d.ts.map +1 -0
  94. package/dist/types/core/usageLimit/types.d.ts.map +1 -0
  95. package/dist/types/index.d.ts +3 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/types/mocks.d.ts +5 -0
  98. package/dist/types/mocks.d.ts.map +1 -0
  99. package/dist/{declarations/src → types}/node/index.d.ts +8 -8
  100. package/dist/types/node/index.d.ts.map +1 -0
  101. package/package.json +36 -29
  102. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.d.ts +0 -2
  103. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.d.ts.map +0 -1
  104. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.dev.js +0 -226
  105. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.js +0 -7
  106. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.prod.js +0 -226
  107. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.esm.js +0 -212
  108. package/cf-worker/package.json +0 -4
  109. package/dist/client-8440b8fb.esm.js +0 -195
  110. package/dist/client-84e46164.cjs.prod.js +0 -203
  111. package/dist/client-a5cc5822.cjs.dev.js +0 -203
  112. package/dist/declarations/src/cf-worker/index.d.ts.map +0 -1
  113. package/dist/declarations/src/cf-worker/usage.d.ts.map +0 -1
  114. package/dist/declarations/src/core/api.d.ts.map +0 -1
  115. package/dist/declarations/src/core/authorize/client.d.ts.map +0 -1
  116. package/dist/declarations/src/core/authorize/index.d.ts.map +0 -1
  117. package/dist/declarations/src/core/authorize/service.d.ts.map +0 -1
  118. package/dist/declarations/src/core/authorize/types.d.ts.map +0 -1
  119. package/dist/declarations/src/core/rateLimit/index.d.ts.map +0 -1
  120. package/dist/declarations/src/core/rateLimit/types.d.ts.map +0 -1
  121. package/dist/declarations/src/core/services.d.ts.map +0 -1
  122. package/dist/declarations/src/core/types.d.ts.map +0 -1
  123. package/dist/declarations/src/core/usage.d.ts.map +0 -1
  124. package/dist/declarations/src/core/usageLimit/index.d.ts +0 -5
  125. package/dist/declarations/src/core/usageLimit/index.d.ts.map +0 -1
  126. package/dist/declarations/src/core/usageLimit/types.d.ts.map +0 -1
  127. package/dist/declarations/src/index.d.ts +0 -3
  128. package/dist/declarations/src/index.d.ts.map +0 -1
  129. package/dist/declarations/src/node/index.d.ts.map +0 -1
  130. package/dist/index-23f268d8.cjs.prod.js +0 -540
  131. package/dist/index-5dc16842.esm.js +0 -535
  132. package/dist/index-88f1ffb6.cjs.dev.js +0 -540
  133. package/dist/thirdweb-dev-service-utils.cjs.d.ts +0 -2
  134. package/dist/thirdweb-dev-service-utils.cjs.d.ts.map +0 -1
  135. package/dist/thirdweb-dev-service-utils.cjs.dev.js +0 -14
  136. package/dist/thirdweb-dev-service-utils.cjs.js +0 -7
  137. package/dist/thirdweb-dev-service-utils.cjs.prod.js +0 -14
  138. package/dist/thirdweb-dev-service-utils.esm.js +0 -1
  139. package/node/dist/thirdweb-dev-service-utils-node.cjs.d.ts +0 -2
  140. package/node/dist/thirdweb-dev-service-utils-node.cjs.d.ts.map +0 -1
  141. package/node/dist/thirdweb-dev-service-utils-node.cjs.dev.js +0 -190
  142. package/node/dist/thirdweb-dev-service-utils-node.cjs.js +0 -7
  143. package/node/dist/thirdweb-dev-service-utils-node.cjs.prod.js +0 -190
  144. package/node/dist/thirdweb-dev-service-utils-node.esm.js +0 -176
  145. package/node/package.json +0 -4
  146. /package/dist/{declarations/src → types}/core/rateLimit/types.d.ts +0 -0
  147. /package/dist/{declarations/src → types}/core/services.d.ts +0 -0
  148. /package/dist/{declarations/src → types}/core/types.d.ts +0 -0
  149. /package/dist/{declarations/src → types}/core/usageLimit/types.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/node/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,147 @@
1
+ import { authorize } from "../core/authorize/index.js";
2
+ export * from "./usage.js";
3
+ export * from "../core/services.js";
4
+ export * from "../core/rateLimit/index.js";
5
+ export * from "../core/usageLimit/index.js";
6
+ const DEFAULT_CACHE_TTL_SECONDS = 60;
7
+ export async function authorizeWorker(authInput, serviceConfig) {
8
+ let authData;
9
+ try {
10
+ authData = await extractAuthorizationData(authInput);
11
+ }
12
+ catch (e) {
13
+ if (e instanceof Error && e.message === "KEY_CONFLICT") {
14
+ return {
15
+ authorized: false,
16
+ status: 400,
17
+ errorMessage: "Please pass either a client id or a secret key.",
18
+ errorCode: "KEY_CONFLICT",
19
+ };
20
+ }
21
+ return {
22
+ authorized: false,
23
+ status: 500,
24
+ errorMessage: "Internal Server Error",
25
+ errorCode: "INTERNAL_SERVER_ERROR",
26
+ };
27
+ }
28
+ return await authorize(authData, serviceConfig, {
29
+ get: async (clientId) => serviceConfig.kvStore.get(clientId),
30
+ put: (clientId, apiKeyMeta) => serviceConfig.ctx.waitUntil(serviceConfig.kvStore.put(clientId, JSON.stringify({
31
+ updatedAt: Date.now(),
32
+ apiKeyMeta,
33
+ }), {
34
+ expirationTtl: serviceConfig.cacheTtlSeconds &&
35
+ serviceConfig.cacheTtlSeconds >= DEFAULT_CACHE_TTL_SECONDS
36
+ ? serviceConfig.cacheTtlSeconds
37
+ : DEFAULT_CACHE_TTL_SECONDS,
38
+ })),
39
+ cacheTtlSeconds: serviceConfig.cacheTtlSeconds ?? DEFAULT_CACHE_TTL_SECONDS,
40
+ });
41
+ }
42
+ export async function extractAuthorizationData(authInput) {
43
+ const requestUrl = new URL(authInput.req.url);
44
+ const headers = authInput.req.headers;
45
+ const secretKey = headers.get("x-secret-key");
46
+ // prefer clientId that is explicitly passed in
47
+ let clientId = authInput.clientId ?? null;
48
+ if (!clientId) {
49
+ // next preference is clientId from header
50
+ clientId = headers.get("x-client-id");
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 = headers.get("x-bundle-id");
58
+ // next preference is search param
59
+ if (!bundleId) {
60
+ bundleId = requestUrl.searchParams.get("bundleId");
61
+ }
62
+ let origin = headers.get("origin");
63
+ // if origin header is not available we'll fall back to referrer;
64
+ if (!origin) {
65
+ origin = headers.get("referer");
66
+ }
67
+ // if we have an origin at this point, normalize it
68
+ if (origin) {
69
+ try {
70
+ origin = new URL(origin).host;
71
+ }
72
+ catch (e) {
73
+ console.warn("failed to parse origin", origin, e);
74
+ }
75
+ }
76
+ // handle if we a secret key is passed in the headers
77
+ let secretKeyHash = null;
78
+ if (secretKey) {
79
+ // hash the secret key
80
+ secretKeyHash = await hashSecretKey(secretKey);
81
+ // derive the client id from the secret key hash
82
+ const derivedClientId = deriveClientIdFromSecretKeyHash(secretKeyHash);
83
+ // if we already have a client id passed in we need to make sure they match
84
+ if (clientId && clientId !== derivedClientId) {
85
+ throw new Error("KEY_CONFLICT");
86
+ }
87
+ // otherwise set the client id to the derived client id (client id based off of secret key)
88
+ clientId = derivedClientId;
89
+ }
90
+ let jwt = null;
91
+ if (headers.has("authorization")) {
92
+ const authHeader = headers.get("authorization");
93
+ if (authHeader) {
94
+ const [type, token] = authHeader.split(" ");
95
+ if (type?.toLowerCase() === "bearer" && !!token) {
96
+ jwt = token;
97
+ }
98
+ }
99
+ }
100
+ return {
101
+ jwt,
102
+ hashedJWT: jwt ? await hashSecretKey(jwt) : null,
103
+ secretKey,
104
+ clientId,
105
+ origin,
106
+ bundleId,
107
+ secretKeyHash,
108
+ targetAddress: authInput.targetAddress,
109
+ };
110
+ }
111
+ export async function hashSecretKey(secretKey) {
112
+ return bufferToHex(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(secretKey)));
113
+ }
114
+ export function deriveClientIdFromSecretKeyHash(secretKeyHash) {
115
+ return secretKeyHash.slice(0, 32);
116
+ }
117
+ function bufferToHex(buffer) {
118
+ return [...new Uint8Array(buffer)]
119
+ .map((x) => x.toString(16).padStart(2, "0"))
120
+ .join("");
121
+ }
122
+ export async function logHttpRequest({ clientId, req, res, isAuthed, statusMessage, latencyMs, }) {
123
+ try {
124
+ const authorizationData = await extractAuthorizationData({ req, clientId });
125
+ const headers = req.headers;
126
+ console.log(JSON.stringify({
127
+ method: req.method,
128
+ pathname: req.url,
129
+ hasSecretKey: !!authorizationData.secretKey,
130
+ hasClientId: !!authorizationData.clientId,
131
+ hasJwt: !!authorizationData.jwt,
132
+ clientId: authorizationData.clientId,
133
+ isAuthed,
134
+ status: res.status,
135
+ sdkName: headers.get("x-sdk-name") ?? undefined,
136
+ sdkVersion: headers.get("x-sdk-version") ?? undefined,
137
+ platform: headers.get("x-sdk-platform") ?? undefined,
138
+ os: headers.get("x-sdk-os") ?? undefined,
139
+ latencyMs,
140
+ }));
141
+ if (statusMessage) {
142
+ console.log(`statusMessage=${statusMessage}`);
143
+ }
144
+ }
145
+ catch { }
146
+ }
147
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cf-worker/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { AwsClient } from "aws4fetch";
2
+ import { usageEventSchema } from "../core/usage.js";
3
+ export {} from "../core/usage.js";
4
+ // Initialize a singleton for AWS usage.
5
+ let _aws;
6
+ function getAws(options) {
7
+ if (!_aws) {
8
+ _aws = new AwsClient(options);
9
+ }
10
+ return _aws;
11
+ }
12
+ /**
13
+ * Publish usage events. Provide the relevant fields for your application.
14
+ *
15
+ * Usage in Cloudflare Workers:
16
+ * ctx.waitUntil(
17
+ * publishUsageEvents(
18
+ * [event1, event2],
19
+ * { queueUrl, accessKeyId, secretAccessKey },
20
+ * )
21
+ * )
22
+ *
23
+ * @param usageEvents
24
+ * @param config
25
+ */
26
+ async function publishUsageEvents(usageEvents, config) {
27
+ const { queueUrl, accessKeyId, secretAccessKey, region = "us-west-2", } = config;
28
+ const entries = usageEvents.map((event) => {
29
+ // Enforce schema of usage event.
30
+ const parsed = usageEventSchema.parse(event);
31
+ return {
32
+ Id: crypto.randomUUID(),
33
+ MessageBody: JSON.stringify(parsed),
34
+ };
35
+ });
36
+ const aws = getAws({
37
+ accessKeyId,
38
+ secretAccessKey,
39
+ region,
40
+ });
41
+ await aws.fetch(`https://sqs.${region}.amazonaws.com`, {
42
+ headers: {
43
+ "X-Amz-Target": "AmazonSQS.SendMessageBatch",
44
+ "X-Amz-Date": new Date().toISOString(),
45
+ "Content-Type": "application/x-amz-json-1.0",
46
+ },
47
+ body: JSON.stringify({
48
+ QueueUrl: queueUrl,
49
+ Entries: entries,
50
+ }),
51
+ });
52
+ }
53
+ export { publishUsageEvents };
54
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/cf-worker/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAmB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAmB,MAAM,kBAAkB,CAAC;AAEnD,wCAAwC;AACxC,IAAI,IAA2B,CAAC;AAChC,SAAS,MAAM,CAAC,OAAmD;IACjE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,kBAAkB,CAC/B,WAAyB,EACzB,MAKC;IAED,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,eAAe,EACf,MAAM,GAAG,WAAW,GACrB,GAAG,MAAM,CAAC;IAEX,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACxC,iCAAiC;QACjC,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;YACvB,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SACpC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,MAAM,CAAC;QACjB,WAAW;QACX,eAAe;QACf,MAAM;KACP,CAAC,CAAC;IACH,MAAM,GAAG,CAAC,KAAK,CAAC,eAAe,MAAM,gBAAgB,EAAE;QACrD,OAAO,EAAE;YACP,cAAc,EAAE,4BAA4B;YAC5C,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACtC,cAAc,EAAE,4BAA4B;SAC7C;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,OAAO;SACjB,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,60 @@
1
+ export async function fetchKeyMetadataFromApi(clientId, config) {
2
+ const { apiUrl, serviceScope, serviceApiKey, checkPolicy, policyMetadata } = config;
3
+ const policyQuery = checkPolicy && policyMetadata
4
+ ? `&checkPolicy=true&policyMetadata=${encodeURIComponent(JSON.stringify(policyMetadata))}`
5
+ : "";
6
+ const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}&includeUsage=true${policyQuery}`;
7
+ const response = await fetch(url, {
8
+ method: "GET",
9
+ headers: {
10
+ "x-service-api-key": serviceApiKey,
11
+ "content-type": "application/json",
12
+ },
13
+ });
14
+ let text = "";
15
+ try {
16
+ text = await response.text();
17
+ return JSON.parse(text);
18
+ }
19
+ catch {
20
+ throw new Error(`Error fetching key metadata from API: ${response.status} - ${text}`);
21
+ }
22
+ }
23
+ export async function fetchAccountFromApi(jwt, config, useWalletAuth) {
24
+ const { apiUrl, serviceApiKey } = config;
25
+ const url = useWalletAuth
26
+ ? `${apiUrl}/v1/wallet/me?includeUsage=true`
27
+ : `${apiUrl}/v1/account/me?includeUsage=true`;
28
+ const response = await fetch(url, {
29
+ method: "GET",
30
+ headers: {
31
+ "x-service-api-key": serviceApiKey,
32
+ "content-type": "application/json",
33
+ authorization: `Bearer ${jwt}`,
34
+ },
35
+ });
36
+ let text = "";
37
+ try {
38
+ text = await response.text();
39
+ return JSON.parse(text);
40
+ }
41
+ catch {
42
+ throw new Error(`Error fetching account from API: ${response.status} - ${text}`);
43
+ }
44
+ }
45
+ export async function updateRateLimitedAt(apiKeyId, config) {
46
+ const { apiUrl, serviceScope: scope, serviceApiKey } = config;
47
+ const url = `${apiUrl}/usage/rateLimit`;
48
+ await fetch(url, {
49
+ method: "PUT",
50
+ headers: {
51
+ "x-service-api-key": serviceApiKey,
52
+ "content-type": "application/json",
53
+ },
54
+ body: JSON.stringify({
55
+ apiKeyId,
56
+ scope,
57
+ }),
58
+ });
59
+ }
60
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/core/api.ts"],"names":[],"mappings":"AAwFA,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAgB,EAChB,MAAyB;IAEzB,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,GACxE,MAAM,CAAC;IACT,MAAM,WAAW,GACf,WAAW,IAAI,cAAc;QAC3B,CAAC,CAAC,oCAAoC,kBAAkB,CACpD,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAC/B,EAAE;QACL,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,GAAG,GAAG,GAAG,MAAM,yBAAyB,QAAQ,UAAU,YAAY,qBAAqB,WAAW,EAAE,CAAC;IAC/G,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,mBAAmB,EAAE,aAAa;YAClC,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;IAEH,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yCAAyC,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAW,EACX,MAAyB,EACzB,aAAsB;IAEtB,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IACzC,MAAM,GAAG,GAAG,aAAa;QACvB,CAAC,CAAC,GAAG,MAAM,iCAAiC;QAC5C,CAAC,CAAC,GAAG,MAAM,kCAAkC,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,mBAAmB,EAAE,aAAa;YAClC,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,GAAG,EAAE;SAC/B;KACF,CAAC,CAAC;IAEH,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,oCAAoC,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,MAAyB;IAEzB,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAE9D,MAAM,GAAG,GAAG,GAAG,MAAM,kBAAkB,CAAC;IAExC,MAAM,KAAK,CAAC,GAAG,EAAE;QACf,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,mBAAmB,EAAE,aAAa;YAClC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,QAAQ;YACR,KAAK;SACN,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,110 @@
1
+ export function authorizeClient(authOptions, apiKeyMeta) {
2
+ const { origin, bundleId, secretKeyHash: providedSecretHash } = authOptions;
3
+ const { domains, bundleIds, secretHash } = apiKeyMeta;
4
+ const authResult = {
5
+ authorized: true,
6
+ apiKeyMeta,
7
+ accountMeta: {
8
+ id: apiKeyMeta.accountId,
9
+ // TODO update this later
10
+ name: "",
11
+ creatorWalletAddress: apiKeyMeta.creatorWalletAddress,
12
+ limits: apiKeyMeta.limits,
13
+ rateLimits: apiKeyMeta.rateLimits,
14
+ usage: apiKeyMeta.usage,
15
+ },
16
+ };
17
+ // check for public restrictions
18
+ if (domains.includes("*")) {
19
+ return authResult;
20
+ }
21
+ // check for secretHash
22
+ if (providedSecretHash) {
23
+ if (secretHash !== providedSecretHash) {
24
+ return {
25
+ authorized: false,
26
+ errorMessage: "Incorrect key provided. You can view your active API keys at https://thirdweb.com/dashboard/settings",
27
+ errorCode: "SECRET_INVALID",
28
+ status: 401,
29
+ };
30
+ }
31
+ return authResult;
32
+ }
33
+ // validate domains
34
+ if (origin) {
35
+ if (authorizeDomain({
36
+ domains,
37
+ origin,
38
+ })) {
39
+ return authResult;
40
+ }
41
+ return {
42
+ authorized: false,
43
+ errorMessage: `Invalid request: Unauthorized domain: ${origin}. You can view the restrictions on this API key at https://thirdweb.com/create-api-key`,
44
+ errorCode: "ORIGIN_UNAUTHORIZED",
45
+ status: 401,
46
+ };
47
+ }
48
+ // validate bundleId
49
+ if (bundleId) {
50
+ if (authorizeBundleId({
51
+ bundleIds,
52
+ bundleId,
53
+ })) {
54
+ return authResult;
55
+ }
56
+ return {
57
+ authorized: false,
58
+ errorMessage: `Invalid request: Unauthorized Bundle ID: ${bundleId}. You can view the restrictions on this API key at https://thirdweb.com/create-api-key`,
59
+ errorCode: "BUNDLE_UNAUTHORIZED",
60
+ status: 401,
61
+ };
62
+ }
63
+ return {
64
+ authorized: false,
65
+ errorMessage: "The keys are invalid. Please check the secret-key/clientId and try again.",
66
+ errorCode: "UNAUTHORIZED",
67
+ status: 401,
68
+ };
69
+ }
70
+ // Exposed for use in validating ecosystem partners settings
71
+ export function authorizeDomain({ domains, origin, }) {
72
+ // find matching domain, or if all domains allowed
73
+ // embedded-wallet.thirdweb(-dev).com is automatically allowed
74
+ // because the rpc is passed from user's domain to embedded-wallet.thirdweb.com iframe for use.
75
+ // Note this doesn't allow embedded-wallets from being used if it's disabled. The service check that runs after enforces that.
76
+ return !![
77
+ ...domains,
78
+ "embedded-wallet.thirdweb.com",
79
+ "embedded-wallet.thirdweb-dev.com",
80
+ ].find((d) => {
81
+ // if any domain is allowed, we'll return true
82
+ if (d === "*") {
83
+ return true;
84
+ }
85
+ // special rule for `localhost`
86
+ // if the domain is localhost, we'll allow any origin that starts with localhost
87
+ if (d === "localhost" && origin.startsWith("localhost")) {
88
+ return true;
89
+ }
90
+ // If the allowedDomain has a wildcard,
91
+ // we'll check that the ending of our domain matches the wildcard
92
+ if (d.startsWith("*.")) {
93
+ // get rid of the * and check if it ends with the `.<domain>.<tld>`
94
+ const domainRoot = d.slice(1);
95
+ return origin.endsWith(domainRoot);
96
+ }
97
+ // If there's no wildcard, we'll check for an exact match
98
+ return d === origin;
99
+ });
100
+ }
101
+ export function authorizeBundleId({ bundleIds, bundleId, }) {
102
+ // find matching bundle id, or if all bundles allowed
103
+ return !!bundleIds.find((b) => {
104
+ if (b === "*") {
105
+ return true;
106
+ }
107
+ return b === bundleId;
108
+ });
109
+ }
110
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/core/authorize/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,212 @@
1
+ import { fetchAccountFromApi, fetchKeyMetadataFromApi, } from "../api.js";
2
+ import { authorizeClient } from "./client.js";
3
+ import { authorizeService } from "./service.js";
4
+ export async function authorize(authData, serviceConfig, cacheOptions) {
5
+ const { clientId, targetAddress, secretKeyHash, jwt, hashedJWT, useWalletAuth, } = authData;
6
+ const { enforceAuth } = serviceConfig;
7
+ // BACKWARDS COMPAT: if auth not enforced and we don't have auth credentials bypass
8
+ if (!enforceAuth && !clientId && !secretKeyHash) {
9
+ return {
10
+ authorized: true,
11
+ apiKeyMeta: null,
12
+ accountMeta: null,
13
+ };
14
+ }
15
+ // if we come in with a JWT then we only check the account is valid
16
+ if (jwt && hashedJWT) {
17
+ let accountMeta = null;
18
+ if (cacheOptions) {
19
+ try {
20
+ const cachedAccountInfo = await cacheOptions.get(hashedJWT);
21
+ if (cachedAccountInfo) {
22
+ const parsed = JSON.parse(cachedAccountInfo);
23
+ if ("updatedAt" in parsed) {
24
+ // we want to compare the updatedAt time to the current time
25
+ // if the difference is greater than the cacheTtl we want to ignore the cached data
26
+ const now = Date.now();
27
+ const diff = now - parsed.updatedAt;
28
+ const cacheTtlMs = cacheOptions.cacheTtlSeconds * 1000;
29
+ // only if the diff is less than the cacheTtl do we want to use the cached key
30
+ if (diff < cacheTtlMs) {
31
+ accountMeta = parsed.apiKeyMeta;
32
+ }
33
+ }
34
+ else {
35
+ accountMeta = parsed;
36
+ }
37
+ }
38
+ }
39
+ catch {
40
+ // ignore errors, proceed as if not in cache
41
+ }
42
+ }
43
+ if (!accountMeta) {
44
+ try {
45
+ const { data, error } = await fetchAccountFromApi(jwt, serviceConfig, useWalletAuth?.toLowerCase() === "true");
46
+ if (error) {
47
+ return {
48
+ authorized: false,
49
+ errorCode: error.code,
50
+ errorMessage: error.message,
51
+ status: error.statusCode,
52
+ };
53
+ }
54
+ if (!data) {
55
+ return {
56
+ authorized: false,
57
+ errorCode: "NO_ACCOUNT",
58
+ errorMessage: "No error but also no account returned.",
59
+ status: 500,
60
+ };
61
+ }
62
+ accountMeta = data;
63
+ if (cacheOptions) {
64
+ await cacheOptions.put(hashedJWT, accountMeta);
65
+ }
66
+ }
67
+ catch (err) {
68
+ console.warn("failed to fetch account from api", err);
69
+ return {
70
+ authorized: false,
71
+ status: 500,
72
+ errorMessage: "Failed to get account information.",
73
+ errorCode: "FAILED_TO_LOAD_ACCOUNT",
74
+ };
75
+ }
76
+ }
77
+ // if we still don't have an accountMeta at this point we can't authorize
78
+ if (!accountMeta) {
79
+ return {
80
+ authorized: false,
81
+ status: 401,
82
+ errorMessage: "Missing account information.",
83
+ errorCode: "MISSING_ACCOUNT",
84
+ };
85
+ }
86
+ // otherwise we want to return early with the accountMeta
87
+ return {
88
+ authorized: true,
89
+ apiKeyMeta: null,
90
+ accountMeta,
91
+ };
92
+ }
93
+ // if we don't have a client id at this point we can't authorize
94
+ if (!clientId) {
95
+ return {
96
+ authorized: false,
97
+ status: 401,
98
+ errorMessage: "Missing clientId or secretKey.",
99
+ errorCode: "MISSING_KEY",
100
+ };
101
+ }
102
+ let apiKeyMeta = null;
103
+ // if we have cache options we want to check the cache first
104
+ if (cacheOptions) {
105
+ try {
106
+ const cachedKey = await cacheOptions.get(clientId);
107
+ if (cachedKey) {
108
+ const parsed = JSON.parse(cachedKey);
109
+ if ("updatedAt" in parsed) {
110
+ // we want to compare the updatedAt time to the current time
111
+ // if the difference is greater than the cacheTtl we want to ignore the cached data
112
+ const now = Date.now();
113
+ const diff = now - parsed.updatedAt;
114
+ const cacheTtlMs = cacheOptions.cacheTtlSeconds * 1000;
115
+ // only if the diff is less than the cacheTtl do we want to use the cached key
116
+ if (diff < cacheTtlMs) {
117
+ apiKeyMeta = parsed.apiKeyMeta;
118
+ }
119
+ }
120
+ else {
121
+ apiKeyMeta = parsed;
122
+ }
123
+ }
124
+ }
125
+ catch {
126
+ // ignore errors, proceed as if not in cache
127
+ }
128
+ }
129
+ // if we don't have a cached key, fetch from the API
130
+ if (!apiKeyMeta) {
131
+ try {
132
+ const { data, error } = await fetchKeyMetadataFromApi(clientId, serviceConfig);
133
+ if (error) {
134
+ return {
135
+ authorized: false,
136
+ errorCode: error.code,
137
+ errorMessage: error.message,
138
+ status: error.statusCode,
139
+ };
140
+ }
141
+ if (!data) {
142
+ return {
143
+ authorized: false,
144
+ errorCode: "NO_KEY",
145
+ errorMessage: "No error but also no key returned.",
146
+ status: 500,
147
+ };
148
+ }
149
+ // if we have a key for sure then assign it
150
+ apiKeyMeta = data;
151
+ // cache the retrieved key if we have cache options
152
+ if (cacheOptions) {
153
+ // we await this always because it can be a promise or not
154
+ await cacheOptions.put(clientId, data);
155
+ }
156
+ }
157
+ catch (err) {
158
+ console.warn("failed to fetch key metadata from api", err);
159
+ return {
160
+ authorized: false,
161
+ status: 500,
162
+ errorMessage: "Failed to fetch key metadata. Please check your secret-key/clientId.",
163
+ errorCode: "FAILED_TO_FETCH_KEY",
164
+ };
165
+ }
166
+ }
167
+ if (!apiKeyMeta) {
168
+ return {
169
+ authorized: false,
170
+ status: 401,
171
+ errorMessage: "Key is invalid. Please check your secret-key/clientId.",
172
+ errorCode: "INVALID_KEY",
173
+ };
174
+ }
175
+ // now we can validate the key itself
176
+ const clientAuth = authorizeClient(authData, apiKeyMeta);
177
+ if (!clientAuth.authorized) {
178
+ return {
179
+ errorCode: clientAuth.errorCode,
180
+ authorized: false,
181
+ status: 401,
182
+ errorMessage: clientAuth.errorMessage,
183
+ };
184
+ }
185
+ // if we've made it this far we need to check service specific authorization
186
+ const serviceAuth = authorizeService(apiKeyMeta, serviceConfig, {
187
+ targetAddress,
188
+ });
189
+ if (!serviceAuth.authorized) {
190
+ return {
191
+ errorCode: serviceAuth.errorCode,
192
+ authorized: false,
193
+ status: 403,
194
+ errorMessage: serviceAuth.errorMessage,
195
+ };
196
+ }
197
+ // if we reach this point we are authorized!
198
+ return {
199
+ authorized: true,
200
+ apiKeyMeta,
201
+ accountMeta: {
202
+ id: apiKeyMeta.accountId,
203
+ // TODO update this later
204
+ name: "",
205
+ limits: apiKeyMeta.limits,
206
+ rateLimits: apiKeyMeta.rateLimits,
207
+ usage: apiKeyMeta.usage,
208
+ creatorWalletAddress: apiKeyMeta.creatorWalletAddress,
209
+ },
210
+ };
211
+ }
212
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/authorize/index.ts"],"names":[],"mappings":"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"}