@drawbridge/drawbridge-utils 0.0.42 → 0.0.43
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/ai.cjs +4 -4
- package/dist/ai.js +127 -8
- package/dist/axios.cjs +1 -1
- package/dist/axios.js +1 -1
- package/dist/cdn.cjs +1 -1
- package/dist/cdn.js +1 -1
- package/dist/circuit.cjs +1 -1
- package/dist/circuit.js +50 -3
- package/dist/encrypt.cjs +3 -3
- package/dist/encrypt.js +38 -5
- package/dist/fetch.cjs +1 -1
- package/dist/fetch.js +1 -1
- package/dist/http.cjs +1 -1
- package/dist/http.js +1 -1
- package/dist/nanoid.cjs +1 -1
- package/dist/nanoid.js +1 -1
- package/dist/{oauth.cjs → oauth/index.cjs} +16 -16
- package/dist/{oauth.d.ts → oauth/index.d.cts} +8 -8
- package/dist/{oauth.d.cts → oauth/index.d.ts} +8 -8
- package/dist/{oauth.js → oauth/index.js} +33 -17
- package/dist/oauth/server.cjs +377 -0
- package/dist/oauth/server.d.cts +387 -0
- package/dist/oauth/server.d.ts +387 -0
- package/dist/oauth/server.js +341 -0
- package/dist/orders.cjs +1 -1
- package/dist/orders.js +1 -1
- package/dist/redirect.cjs +1 -1
- package/dist/redirect.js +1 -1
- package/dist/shopify.cjs +5 -5
- package/dist/shopify.js +46 -11
- package/dist/slugify.cjs +1 -1
- package/dist/slugify.js +1 -1
- package/dist/token.cjs +1 -1
- package/dist/token.js +21 -5
- package/dist/transactions.cjs +1 -1
- package/dist/transactions.js +108 -4
- package/dist/upload.cjs +1 -1
- package/dist/upload.js +1 -1
- package/package.json +20 -4
- package/dist/chunk-2DRAIKGZ.js +0 -38
- package/dist/chunk-6HH36OK6.js +0 -54
- package/dist/chunk-JT2PAZAZ.js +0 -113
- package/dist/chunk-OS2AHUWX.js +0 -27
package/dist/ai.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
18
|
|
|
19
|
-
// ai.js
|
|
19
|
+
// lib/ai.js
|
|
20
20
|
var ai_exports = {};
|
|
21
21
|
__export(ai_exports, {
|
|
22
22
|
MARKUP: () => MARKUP,
|
|
@@ -31,7 +31,7 @@ __export(ai_exports, {
|
|
|
31
31
|
module.exports = __toCommonJS(ai_exports);
|
|
32
32
|
var import_genai = require("@google/genai");
|
|
33
33
|
|
|
34
|
-
// circuit.js
|
|
34
|
+
// lib/circuit.js
|
|
35
35
|
var CLOSED = "CLOSED";
|
|
36
36
|
var OPEN = "OPEN";
|
|
37
37
|
var HALF_OPEN = "HALF_OPEN";
|
|
@@ -82,7 +82,7 @@ var circuit = ({
|
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
// transactions.js
|
|
85
|
+
// lib/transactions.js
|
|
86
86
|
var import_drawbridge_telemetry = require("@drawbridge/drawbridge-telemetry");
|
|
87
87
|
var insertTransaction = async ({
|
|
88
88
|
db,
|
|
@@ -155,7 +155,7 @@ var debit = async ({
|
|
|
155
155
|
});
|
|
156
156
|
};
|
|
157
157
|
|
|
158
|
-
// ai.js
|
|
158
|
+
// lib/ai.js
|
|
159
159
|
var google_client = new import_genai.GoogleGenAI({
|
|
160
160
|
apiKey: process.env.GOOGLE_API_KEY
|
|
161
161
|
});
|
package/dist/ai.js
CHANGED
|
@@ -1,12 +1,131 @@
|
|
|
1
|
-
|
|
2
|
-
debit
|
|
3
|
-
} from "./chunk-JT2PAZAZ.js";
|
|
4
|
-
import {
|
|
5
|
-
circuit
|
|
6
|
-
} from "./chunk-6HH36OK6.js";
|
|
7
|
-
|
|
8
|
-
// ai.js
|
|
1
|
+
// lib/ai.js
|
|
9
2
|
import { GoogleGenAI } from "@google/genai";
|
|
3
|
+
|
|
4
|
+
// lib/circuit.js
|
|
5
|
+
var CLOSED = "CLOSED";
|
|
6
|
+
var OPEN = "OPEN";
|
|
7
|
+
var HALF_OPEN = "HALF_OPEN";
|
|
8
|
+
var circuit = ({
|
|
9
|
+
name,
|
|
10
|
+
threshold = 5,
|
|
11
|
+
timeout = 3e4
|
|
12
|
+
}) => {
|
|
13
|
+
let state = CLOSED;
|
|
14
|
+
let failures = 0;
|
|
15
|
+
let openedAt = null;
|
|
16
|
+
const trip = () => {
|
|
17
|
+
state = OPEN;
|
|
18
|
+
openedAt = Date.now();
|
|
19
|
+
console.error(`Circuit breaker OPEN: ${name}`);
|
|
20
|
+
};
|
|
21
|
+
const reset = () => {
|
|
22
|
+
state = CLOSED;
|
|
23
|
+
failures = 0;
|
|
24
|
+
openedAt = null;
|
|
25
|
+
console.log(`Circuit breaker CLOSED: ${name}`);
|
|
26
|
+
};
|
|
27
|
+
return async (fn) => {
|
|
28
|
+
if (state === OPEN) {
|
|
29
|
+
if (Date.now() - openedAt >= timeout) {
|
|
30
|
+
state = HALF_OPEN;
|
|
31
|
+
} else {
|
|
32
|
+
const error = new Error(`${name} is temporarily unavailable`);
|
|
33
|
+
error.status = 503;
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const result = await fn();
|
|
39
|
+
if (state === HALF_OPEN) {
|
|
40
|
+
reset();
|
|
41
|
+
} else {
|
|
42
|
+
failures = 0;
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
failures++;
|
|
47
|
+
if (state === HALF_OPEN || failures >= threshold) {
|
|
48
|
+
trip();
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// lib/transactions.js
|
|
56
|
+
import { currentTraceId } from "@drawbridge/drawbridge-telemetry";
|
|
57
|
+
var insertTransaction = async ({
|
|
58
|
+
db,
|
|
59
|
+
user,
|
|
60
|
+
type,
|
|
61
|
+
category,
|
|
62
|
+
source,
|
|
63
|
+
amount,
|
|
64
|
+
_id,
|
|
65
|
+
stripeInvoiceId,
|
|
66
|
+
stripeEventId,
|
|
67
|
+
session,
|
|
68
|
+
...rest
|
|
69
|
+
}) => {
|
|
70
|
+
var _a;
|
|
71
|
+
const beforeRaw = (_a = user == null ? void 0 : user.balance) == null ? void 0 : _a[type];
|
|
72
|
+
const balance = typeof beforeRaw === "number" ? { before: beforeRaw, after: beforeRaw + amount } : void 0;
|
|
73
|
+
const trace = currentTraceId();
|
|
74
|
+
await db.create({
|
|
75
|
+
authenticated: user,
|
|
76
|
+
collection: "transaction",
|
|
77
|
+
data: {
|
|
78
|
+
..._id && { _id },
|
|
79
|
+
user: user == null ? void 0 : user.id,
|
|
80
|
+
type,
|
|
81
|
+
category,
|
|
82
|
+
source,
|
|
83
|
+
amount,
|
|
84
|
+
...balance && { balance },
|
|
85
|
+
...trace && { trace },
|
|
86
|
+
...rest,
|
|
87
|
+
...stripeInvoiceId && { stripeInvoiceId },
|
|
88
|
+
...stripeEventId && { stripeEventId }
|
|
89
|
+
},
|
|
90
|
+
...session && { options: { session } }
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
var debit = async ({
|
|
94
|
+
db,
|
|
95
|
+
user,
|
|
96
|
+
amount,
|
|
97
|
+
type,
|
|
98
|
+
category,
|
|
99
|
+
source,
|
|
100
|
+
stripeInvoiceId,
|
|
101
|
+
stripeEventId,
|
|
102
|
+
session,
|
|
103
|
+
...rest
|
|
104
|
+
}) => {
|
|
105
|
+
if (!Number.isInteger(amount) || amount <= 0) {
|
|
106
|
+
throw new Error(`debit() requires a positive integer amount, got ${amount}`);
|
|
107
|
+
}
|
|
108
|
+
if (!type) {
|
|
109
|
+
throw new Error('debit() requires a type (e.g., "ai")');
|
|
110
|
+
}
|
|
111
|
+
if (!source) {
|
|
112
|
+
throw new Error('debit() requires a source ("system" | "admin" | "user")');
|
|
113
|
+
}
|
|
114
|
+
await insertTransaction({
|
|
115
|
+
db,
|
|
116
|
+
user,
|
|
117
|
+
type,
|
|
118
|
+
category,
|
|
119
|
+
source,
|
|
120
|
+
amount: -amount,
|
|
121
|
+
stripeInvoiceId,
|
|
122
|
+
stripeEventId,
|
|
123
|
+
session,
|
|
124
|
+
...rest
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// lib/ai.js
|
|
10
129
|
var google_client = new GoogleGenAI({
|
|
11
130
|
apiKey: process.env.GOOGLE_API_KEY
|
|
12
131
|
});
|
package/dist/axios.cjs
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
));
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
|
-
// axios.js
|
|
29
|
+
// lib/axios.js
|
|
30
30
|
var axios_exports = {};
|
|
31
31
|
__export(axios_exports, {
|
|
32
32
|
axios: () => axios,
|
package/dist/axios.js
CHANGED
package/dist/cdn.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
18
|
|
|
19
|
-
// cdn.js
|
|
19
|
+
// lib/cdn.js
|
|
20
20
|
var cdn_exports = {};
|
|
21
21
|
__export(cdn_exports, {
|
|
22
22
|
cdnShopify: () => cdnShopify,
|
package/dist/cdn.js
CHANGED
package/dist/circuit.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
18
|
|
|
19
|
-
// circuit.js
|
|
19
|
+
// lib/circuit.js
|
|
20
20
|
var circuit_exports = {};
|
|
21
21
|
__export(circuit_exports, {
|
|
22
22
|
circuit: () => circuit
|
package/dist/circuit.js
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// lib/circuit.js
|
|
2
|
+
var CLOSED = "CLOSED";
|
|
3
|
+
var OPEN = "OPEN";
|
|
4
|
+
var HALF_OPEN = "HALF_OPEN";
|
|
5
|
+
var circuit = ({
|
|
6
|
+
name,
|
|
7
|
+
threshold = 5,
|
|
8
|
+
timeout = 3e4
|
|
9
|
+
}) => {
|
|
10
|
+
let state = CLOSED;
|
|
11
|
+
let failures = 0;
|
|
12
|
+
let openedAt = null;
|
|
13
|
+
const trip = () => {
|
|
14
|
+
state = OPEN;
|
|
15
|
+
openedAt = Date.now();
|
|
16
|
+
console.error(`Circuit breaker OPEN: ${name}`);
|
|
17
|
+
};
|
|
18
|
+
const reset = () => {
|
|
19
|
+
state = CLOSED;
|
|
20
|
+
failures = 0;
|
|
21
|
+
openedAt = null;
|
|
22
|
+
console.log(`Circuit breaker CLOSED: ${name}`);
|
|
23
|
+
};
|
|
24
|
+
return async (fn) => {
|
|
25
|
+
if (state === OPEN) {
|
|
26
|
+
if (Date.now() - openedAt >= timeout) {
|
|
27
|
+
state = HALF_OPEN;
|
|
28
|
+
} else {
|
|
29
|
+
const error = new Error(`${name} is temporarily unavailable`);
|
|
30
|
+
error.status = 503;
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const result = await fn();
|
|
36
|
+
if (state === HALF_OPEN) {
|
|
37
|
+
reset();
|
|
38
|
+
} else {
|
|
39
|
+
failures = 0;
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
failures++;
|
|
44
|
+
if (state === HALF_OPEN || failures >= threshold) {
|
|
45
|
+
trip();
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
4
51
|
export {
|
|
5
52
|
circuit
|
|
6
53
|
};
|
package/dist/encrypt.cjs
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
));
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
|
-
// encrypt.js
|
|
29
|
+
// lib/encrypt.js
|
|
30
30
|
var encrypt_exports = {};
|
|
31
31
|
__export(encrypt_exports, {
|
|
32
32
|
decrypt: () => decrypt,
|
|
@@ -35,14 +35,14 @@ __export(encrypt_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(encrypt_exports);
|
|
36
36
|
var import_crypto2 = __toESM(require("crypto"), 1);
|
|
37
37
|
|
|
38
|
-
// token.js
|
|
38
|
+
// lib/token.js
|
|
39
39
|
var import_crypto = __toESM(require("crypto"), 1);
|
|
40
40
|
var generate = (bytes = 32, encoding = "base64url") => {
|
|
41
41
|
const buf = import_crypto.default.randomBytes(bytes);
|
|
42
42
|
return encoding ? buf.toString(encoding) : buf;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
// encrypt.js
|
|
45
|
+
// lib/encrypt.js
|
|
46
46
|
var ALGORITHM = "aes-256-gcm";
|
|
47
47
|
var getKey = () => Buffer.from(process.env.ENCRYPT_CONNECTION_SECRET, "hex");
|
|
48
48
|
var encrypt = (value) => {
|
package/dist/encrypt.js
CHANGED
|
@@ -1,8 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import "
|
|
1
|
+
// lib/encrypt.js
|
|
2
|
+
import crypto2 from "crypto";
|
|
3
|
+
|
|
4
|
+
// lib/token.js
|
|
5
|
+
import crypto from "crypto";
|
|
6
|
+
var generate = (bytes = 32, encoding = "base64url") => {
|
|
7
|
+
const buf = crypto.randomBytes(bytes);
|
|
8
|
+
return encoding ? buf.toString(encoding) : buf;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// lib/encrypt.js
|
|
12
|
+
var ALGORITHM = "aes-256-gcm";
|
|
13
|
+
var getKey = () => Buffer.from(process.env.ENCRYPT_CONNECTION_SECRET, "hex");
|
|
14
|
+
var encrypt = (value) => {
|
|
15
|
+
const iv = generate(12, null);
|
|
16
|
+
const cipher = crypto2.createCipheriv(ALGORITHM, getKey(), iv);
|
|
17
|
+
const data = Buffer.concat([
|
|
18
|
+
cipher.update(JSON.stringify(value), "utf8"),
|
|
19
|
+
cipher.final()
|
|
20
|
+
]);
|
|
21
|
+
const tag = cipher.getAuthTag();
|
|
22
|
+
return [iv, tag, data].map((b) => b.toString("hex")).join(":");
|
|
23
|
+
};
|
|
24
|
+
var decrypt = (value) => {
|
|
25
|
+
if (typeof value !== "string") return value;
|
|
26
|
+
const [ivHex, tagHex, dataHex] = value.split(":");
|
|
27
|
+
const decipher = crypto2.createDecipheriv(
|
|
28
|
+
ALGORITHM,
|
|
29
|
+
getKey(),
|
|
30
|
+
Buffer.from(ivHex, "hex")
|
|
31
|
+
);
|
|
32
|
+
decipher.setAuthTag(Buffer.from(tagHex, "hex"));
|
|
33
|
+
const result = Buffer.concat([
|
|
34
|
+
decipher.update(Buffer.from(dataHex, "hex")),
|
|
35
|
+
decipher.final()
|
|
36
|
+
]);
|
|
37
|
+
return JSON.parse(result.toString("utf8"));
|
|
38
|
+
};
|
|
6
39
|
export {
|
|
7
40
|
decrypt,
|
|
8
41
|
encrypt
|
package/dist/fetch.cjs
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
));
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
|
-
// fetch.js
|
|
29
|
+
// lib/fetch.js
|
|
30
30
|
var fetch_exports = {};
|
|
31
31
|
__export(fetch_exports, {
|
|
32
32
|
queryString: () => queryString,
|
package/dist/fetch.js
CHANGED
package/dist/http.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
18
|
|
|
19
|
-
// http.js
|
|
19
|
+
// lib/http.js
|
|
20
20
|
var http_exports = {};
|
|
21
21
|
__export(http_exports, {
|
|
22
22
|
request: () => request
|
package/dist/http.js
CHANGED
package/dist/nanoid.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
18
|
|
|
19
|
-
// nanoid.js
|
|
19
|
+
// lib/nanoid.js
|
|
20
20
|
var nanoid_exports = {};
|
|
21
21
|
__export(nanoid_exports, {
|
|
22
22
|
nanoid: () => nanoid,
|
package/dist/nanoid.js
CHANGED
|
@@ -26,23 +26,23 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
));
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
|
-
// oauth.js
|
|
29
|
+
// lib/oauth/index.js
|
|
30
30
|
var oauth_exports = {};
|
|
31
31
|
__export(oauth_exports, {
|
|
32
|
-
DEVELOPER_ALLOWED_SCOPES: () => DEVELOPER_ALLOWED_SCOPES,
|
|
33
|
-
SCOPES: () => SCOPES,
|
|
34
32
|
compare: () => compare,
|
|
35
33
|
createOAuthClient: () => createOAuthClient,
|
|
34
|
+
developer: () => developer,
|
|
36
35
|
generateToken: () => generateToken,
|
|
37
36
|
hashToken: () => hashToken,
|
|
38
37
|
intersect: () => intersect,
|
|
39
38
|
isDeveloperAllowed: () => isDeveloperAllowed,
|
|
40
39
|
parse: () => parse,
|
|
40
|
+
scopes: () => scopes,
|
|
41
41
|
validate: () => validate
|
|
42
42
|
});
|
|
43
43
|
module.exports = __toCommonJS(oauth_exports);
|
|
44
44
|
|
|
45
|
-
// token.js
|
|
45
|
+
// lib/token.js
|
|
46
46
|
var import_crypto = __toESM(require("crypto"), 1);
|
|
47
47
|
var generate = (bytes = 32, encoding = "base64url") => {
|
|
48
48
|
const buf = import_crypto.default.randomBytes(bytes);
|
|
@@ -64,8 +64,8 @@ var compare = (a, b) => {
|
|
|
64
64
|
);
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
// oauth.js
|
|
68
|
-
var
|
|
67
|
+
// lib/oauth/index.js
|
|
68
|
+
var scopes = [
|
|
69
69
|
"profile:read",
|
|
70
70
|
"profile:write",
|
|
71
71
|
"organization:read",
|
|
@@ -82,7 +82,7 @@ var SCOPES = [
|
|
|
82
82
|
"billing:write",
|
|
83
83
|
"admin"
|
|
84
84
|
];
|
|
85
|
-
var
|
|
85
|
+
var developer = [
|
|
86
86
|
"profile:read",
|
|
87
87
|
"organization:read",
|
|
88
88
|
"campaigns:read",
|
|
@@ -99,9 +99,9 @@ var parse = (raw) => {
|
|
|
99
99
|
if (Array.isArray(raw)) return raw;
|
|
100
100
|
return String(raw).split(/\s+/).filter(Boolean);
|
|
101
101
|
};
|
|
102
|
-
var validate = (
|
|
103
|
-
const parsed = parse(
|
|
104
|
-
const invalid = parsed.filter((scope) => !
|
|
102
|
+
var validate = (scopes2) => {
|
|
103
|
+
const parsed = parse(scopes2);
|
|
104
|
+
const invalid = parsed.filter((scope) => !scopes2.includes(scope));
|
|
105
105
|
return {
|
|
106
106
|
invalid,
|
|
107
107
|
valid: invalid.length === 0
|
|
@@ -112,14 +112,14 @@ var intersect = (requested, allowed) => {
|
|
|
112
112
|
const a = parse(allowed);
|
|
113
113
|
return r.filter((scope) => a.includes(scope));
|
|
114
114
|
};
|
|
115
|
-
var isDeveloperAllowed = (scope) =>
|
|
115
|
+
var isDeveloperAllowed = (scope) => developer.includes(scope);
|
|
116
116
|
var hashToken = (raw) => hash(raw, process.env.OAUTH_TOKEN_HMAC_KEY);
|
|
117
117
|
var generateToken = () => generate(32, "base64url");
|
|
118
118
|
var REFRESH_LEAD_SECONDS = 60;
|
|
119
119
|
var createOAuthClient = ({
|
|
120
120
|
clientId,
|
|
121
121
|
clientSecret,
|
|
122
|
-
scopes = [],
|
|
122
|
+
scopes: scopes2 = [],
|
|
123
123
|
tokenUri
|
|
124
124
|
}) => {
|
|
125
125
|
if (!clientId) throw new Error("createOAuthClient: clientId required");
|
|
@@ -135,8 +135,8 @@ var createOAuthClient = ({
|
|
|
135
135
|
const fetchToken = async () => {
|
|
136
136
|
const params = new URLSearchParams();
|
|
137
137
|
params.set("grant_type", "client_credentials");
|
|
138
|
-
if (
|
|
139
|
-
params.set("scope",
|
|
138
|
+
if (scopes2.length > 0) {
|
|
139
|
+
params.set("scope", scopes2.join(" "));
|
|
140
140
|
}
|
|
141
141
|
const basic = Buffer.from(clientId + ":" + clientSecret).toString("base64");
|
|
142
142
|
const response = await fetch(
|
|
@@ -183,14 +183,14 @@ var createOAuthClient = ({
|
|
|
183
183
|
};
|
|
184
184
|
// Annotate the CommonJS export names for ESM import in node:
|
|
185
185
|
0 && (module.exports = {
|
|
186
|
-
DEVELOPER_ALLOWED_SCOPES,
|
|
187
|
-
SCOPES,
|
|
188
186
|
compare,
|
|
189
187
|
createOAuthClient,
|
|
188
|
+
developer,
|
|
190
189
|
generateToken,
|
|
191
190
|
hashToken,
|
|
192
191
|
intersect,
|
|
193
192
|
isDeveloperAllowed,
|
|
194
193
|
parse,
|
|
194
|
+
scopes,
|
|
195
195
|
validate
|
|
196
196
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { generate, hash } from '
|
|
2
|
-
export { compare } from '
|
|
1
|
+
import { generate, hash } from '../token.cjs';
|
|
2
|
+
export { compare } from '../token.cjs';
|
|
3
3
|
import 'crypto';
|
|
4
4
|
|
|
5
5
|
// Shared OAuth helpers used across drawbridge-api, drawbridge-sync,
|
|
6
6
|
// drawbridge-app-web, and any first-party app that needs to participate
|
|
7
7
|
// in the OAuth 2.1 provider:
|
|
8
8
|
//
|
|
9
|
-
// -
|
|
9
|
+
// - scopes, developer: the locked scope vocabulary
|
|
10
10
|
// - parse, validate, intersect, isDeveloperAllowed: scope set operations
|
|
11
11
|
// - hashToken, generateToken, compare: opaque-token primitives
|
|
12
12
|
// - createOAuthClient: cached client_credentials access token getter
|
|
@@ -16,7 +16,7 @@ import 'crypto';
|
|
|
16
16
|
// Scope vocabulary (locked — 15 scopes, 10 in the developer-allowed subset)
|
|
17
17
|
// ─────────────────────────────────────────────────────────────────────────
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const scopes = [
|
|
20
20
|
'profile:read',
|
|
21
21
|
'profile:write',
|
|
22
22
|
'organization:read',
|
|
@@ -37,7 +37,7 @@ const SCOPES = [
|
|
|
37
37
|
// Subset granted to third-party developer apps via /oauth/clients self-service
|
|
38
38
|
// registration. Excludes profile:write (account-level), organization:write
|
|
39
39
|
// (org admin only), billing:* (financial), admin (privileged).
|
|
40
|
-
const
|
|
40
|
+
const developer = [
|
|
41
41
|
'profile:read',
|
|
42
42
|
'organization:read',
|
|
43
43
|
'campaigns:read',
|
|
@@ -63,7 +63,7 @@ const parse = ( raw ) => {
|
|
|
63
63
|
const validate = ( scopes ) => {
|
|
64
64
|
|
|
65
65
|
const parsed = parse( scopes );
|
|
66
|
-
const invalid = parsed.filter( ( scope ) => !
|
|
66
|
+
const invalid = parsed.filter( ( scope ) => ! scopes.includes( scope ) );
|
|
67
67
|
|
|
68
68
|
return {
|
|
69
69
|
invalid,
|
|
@@ -81,7 +81,7 @@ const intersect = ( requested, allowed ) => {
|
|
|
81
81
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
const isDeveloperAllowed = ( scope ) =>
|
|
84
|
+
const isDeveloperAllowed = ( scope ) => developer.includes( scope );
|
|
85
85
|
|
|
86
86
|
// ─────────────────────────────────────────────────────────────────────────
|
|
87
87
|
// Token primitives — convenience wrappers over drawbridge-utils/token that
|
|
@@ -228,4 +228,4 @@ const createOAuthClient = ({
|
|
|
228
228
|
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
-
export {
|
|
231
|
+
export { createOAuthClient, developer, generateToken, hashToken, intersect, isDeveloperAllowed, parse, scopes, validate };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { generate, hash } from '
|
|
2
|
-
export { compare } from '
|
|
1
|
+
import { generate, hash } from '../token.js';
|
|
2
|
+
export { compare } from '../token.js';
|
|
3
3
|
import 'crypto';
|
|
4
4
|
|
|
5
5
|
// Shared OAuth helpers used across drawbridge-api, drawbridge-sync,
|
|
6
6
|
// drawbridge-app-web, and any first-party app that needs to participate
|
|
7
7
|
// in the OAuth 2.1 provider:
|
|
8
8
|
//
|
|
9
|
-
// -
|
|
9
|
+
// - scopes, developer: the locked scope vocabulary
|
|
10
10
|
// - parse, validate, intersect, isDeveloperAllowed: scope set operations
|
|
11
11
|
// - hashToken, generateToken, compare: opaque-token primitives
|
|
12
12
|
// - createOAuthClient: cached client_credentials access token getter
|
|
@@ -16,7 +16,7 @@ import 'crypto';
|
|
|
16
16
|
// Scope vocabulary (locked — 15 scopes, 10 in the developer-allowed subset)
|
|
17
17
|
// ─────────────────────────────────────────────────────────────────────────
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const scopes = [
|
|
20
20
|
'profile:read',
|
|
21
21
|
'profile:write',
|
|
22
22
|
'organization:read',
|
|
@@ -37,7 +37,7 @@ const SCOPES = [
|
|
|
37
37
|
// Subset granted to third-party developer apps via /oauth/clients self-service
|
|
38
38
|
// registration. Excludes profile:write (account-level), organization:write
|
|
39
39
|
// (org admin only), billing:* (financial), admin (privileged).
|
|
40
|
-
const
|
|
40
|
+
const developer = [
|
|
41
41
|
'profile:read',
|
|
42
42
|
'organization:read',
|
|
43
43
|
'campaigns:read',
|
|
@@ -63,7 +63,7 @@ const parse = ( raw ) => {
|
|
|
63
63
|
const validate = ( scopes ) => {
|
|
64
64
|
|
|
65
65
|
const parsed = parse( scopes );
|
|
66
|
-
const invalid = parsed.filter( ( scope ) => !
|
|
66
|
+
const invalid = parsed.filter( ( scope ) => ! scopes.includes( scope ) );
|
|
67
67
|
|
|
68
68
|
return {
|
|
69
69
|
invalid,
|
|
@@ -81,7 +81,7 @@ const intersect = ( requested, allowed ) => {
|
|
|
81
81
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
const isDeveloperAllowed = ( scope ) =>
|
|
84
|
+
const isDeveloperAllowed = ( scope ) => developer.includes( scope );
|
|
85
85
|
|
|
86
86
|
// ─────────────────────────────────────────────────────────────────────────
|
|
87
87
|
// Token primitives — convenience wrappers over drawbridge-utils/token that
|
|
@@ -228,4 +228,4 @@ const createOAuthClient = ({
|
|
|
228
228
|
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
-
export {
|
|
231
|
+
export { createOAuthClient, developer, generateToken, hashToken, intersect, isDeveloperAllowed, parse, scopes, validate };
|