@sendbird/cli 0.0.0-stage → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +11 -0
- package/.codex-plugin/plugin.json +39 -0
- package/LICENSE +13 -0
- package/NOTICE.md +1105 -0
- package/PROVENANCE.md +15 -0
- package/README.md +44 -2
- package/dist/acl.d.ts +2 -0
- package/dist/acl.js +12 -0
- package/dist/acl.js.map +1 -0
- package/dist/billing-plan.d.ts +68 -0
- package/dist/billing-plan.js +235 -0
- package/dist/billing-plan.js.map +1 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +20 -0
- package/dist/browser.js.map +1 -0
- package/dist/calls-catalog.d.ts +79 -0
- package/dist/calls-catalog.js +322 -0
- package/dist/calls-catalog.js.map +1 -0
- package/dist/calls-credits.d.ts +31 -0
- package/dist/calls-credits.js +224 -0
- package/dist/calls-credits.js.map +1 -0
- package/dist/calls-trial.d.ts +45 -0
- package/dist/calls-trial.js +77 -0
- package/dist/calls-trial.js.map +1 -0
- package/dist/calls.d.ts +10 -0
- package/dist/calls.js +470 -0
- package/dist/calls.js.map +1 -0
- package/dist/catalog.d.ts +67 -0
- package/dist/catalog.js +784 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +502 -0
- package/dist/cli.js.map +1 -0
- package/dist/core.d.ts +86 -0
- package/dist/core.js +531 -0
- package/dist/core.js.map +1 -0
- package/dist/diagnostics.d.ts +206 -0
- package/dist/diagnostics.js +664 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/discovery.d.ts +703 -0
- package/dist/discovery.js +846 -0
- package/dist/discovery.js.map +1 -0
- package/dist/docs.d.ts +31 -0
- package/dist/docs.js +139 -0
- package/dist/docs.js.map +1 -0
- package/dist/features.d.ts +131 -0
- package/dist/features.js +227 -0
- package/dist/features.js.map +1 -0
- package/dist/generated-api.d.ts +116 -0
- package/dist/generated-api.js +118 -0
- package/dist/generated-api.js.map +1 -0
- package/dist/human-format.d.ts +40 -0
- package/dist/human-format.js +205 -0
- package/dist/human-format.js.map +1 -0
- package/dist/human-list.d.ts +2 -0
- package/dist/human-list.js +368 -0
- package/dist/human-list.js.map +1 -0
- package/dist/human-output.d.ts +10 -0
- package/dist/human-output.js +1351 -0
- package/dist/human-output.js.map +1 -0
- package/dist/human-pro.d.ts +3 -0
- package/dist/human-pro.js +201 -0
- package/dist/human-pro.js.map +1 -0
- package/dist/human-progress.d.ts +5 -0
- package/dist/human-progress.js +49 -0
- package/dist/human-progress.js.map +1 -0
- package/dist/local.d.ts +42 -0
- package/dist/local.js +707 -0
- package/dist/local.js.map +1 -0
- package/dist/oauth-callback.d.ts +3 -0
- package/dist/oauth-callback.js +66 -0
- package/dist/oauth-callback.js.map +1 -0
- package/dist/oauth-lock.d.ts +6 -0
- package/dist/oauth-lock.js +212 -0
- package/dist/oauth-lock.js.map +1 -0
- package/dist/oauth.d.ts +32 -0
- package/dist/oauth.js +493 -0
- package/dist/oauth.js.map +1 -0
- package/dist/presentation.d.ts +208 -0
- package/dist/presentation.js +156 -0
- package/dist/presentation.js.map +1 -0
- package/dist/pro-api-catalog.d.ts +24 -0
- package/dist/pro-api-catalog.js +619 -0
- package/dist/pro-api-catalog.js.map +1 -0
- package/dist/pro-api.d.ts +10 -0
- package/dist/pro-api.js +338 -0
- package/dist/pro-api.js.map +1 -0
- package/dist/project.d.ts +34 -0
- package/dist/project.js +62 -0
- package/dist/project.js.map +1 -0
- package/dist/recovery.d.ts +41 -0
- package/dist/recovery.js +417 -0
- package/dist/recovery.js.map +1 -0
- package/dist/runner.d.ts +47 -0
- package/dist/runner.js +603 -0
- package/dist/runner.js.map +1 -0
- package/dist/sdk-catalog.d.ts +69 -0
- package/dist/sdk-catalog.js +527 -0
- package/dist/sdk-catalog.js.map +1 -0
- package/dist/sdk-config.d.ts +19 -0
- package/dist/sdk-config.js +85 -0
- package/dist/sdk-config.js.map +1 -0
- package/dist/sdk-dto.d.ts +244 -0
- package/dist/sdk-dto.js +98 -0
- package/dist/sdk-dto.js.map +1 -0
- package/dist/sdk-limits.d.ts +2 -0
- package/dist/sdk-limits.js +3 -0
- package/dist/sdk-limits.js.map +1 -0
- package/dist/sdk-node-file-reader.d.ts +6 -0
- package/dist/sdk-node-file-reader.js +38 -0
- package/dist/sdk-node-file-reader.js.map +1 -0
- package/dist/sdk-pro-catalog.d.ts +22 -0
- package/dist/sdk-pro-catalog.js +234 -0
- package/dist/sdk-pro-catalog.js.map +1 -0
- package/dist/sdk-pro-runtime.d.ts +31 -0
- package/dist/sdk-pro-runtime.js +293 -0
- package/dist/sdk-pro-runtime.js.map +1 -0
- package/dist/sdk-query.d.ts +10 -0
- package/dist/sdk-query.js +29 -0
- package/dist/sdk-query.js.map +1 -0
- package/dist/sdk-runtime.d.ts +15 -0
- package/dist/sdk-runtime.js +685 -0
- package/dist/sdk-runtime.js.map +1 -0
- package/dist/sdk-worker.d.ts +1 -0
- package/dist/sdk-worker.js +26 -0
- package/dist/sdk-worker.js.map +1 -0
- package/dist/sdk.d.ts +29 -0
- package/dist/sdk.js +346 -0
- package/dist/sdk.js.map +1 -0
- package/dist/search-engine.d.ts +17 -0
- package/dist/search-engine.js +54 -0
- package/dist/search-engine.js.map +1 -0
- package/dist/search-intents.d.ts +2 -0
- package/dist/search-intents.js +106 -0
- package/dist/search-intents.js.map +1 -0
- package/dist/search.d.ts +7 -0
- package/dist/search.js +58 -0
- package/dist/search.js.map +1 -0
- package/dist/secret-output.d.ts +2 -0
- package/dist/secret-output.js +108 -0
- package/dist/secret-output.js.map +1 -0
- package/dist/shell.d.ts +3 -0
- package/dist/shell.js +14 -0
- package/dist/shell.js.map +1 -0
- package/dist/skills.d.ts +210 -0
- package/dist/skills.js +374 -0
- package/dist/skills.js.map +1 -0
- package/dist/value-semantics.d.ts +70 -0
- package/dist/value-semantics.js +173 -0
- package/dist/value-semantics.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/windows.d.ts +4 -0
- package/dist/windows.js +136 -0
- package/dist/windows.js.map +1 -0
- package/dist/workflows.d.ts +228 -0
- package/dist/workflows.js +1207 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +90 -4
- package/plugin.json +25 -0
- package/references/agent-guide.json +199 -0
- package/references/commands.md +247 -0
- package/references/dashboard-inventory.json +14796 -0
- package/references/docs-index.json +5329 -0
- package/references/sdk-commands.json +15065 -0
- package/references/workflows.json +1246 -0
- package/skills/sendbird/SKILL.md +96 -0
- package/skills/sendbird/agents/openai.yaml +4 -0
- package/skills/sendbird/references/build-chat-app.md +50 -0
- package/skills/sendbird/references/client-guide.md +34 -0
- package/skills/sendbird/references/client-plugin-bridge.md +77 -0
- package/skills/sendbird/references/client-plugin-install.md +39 -0
- package/skills/sendbird/references/operational-checks.md +35 -0
- package/skills/sendbird/references/pro-capabilities.md +52 -0
- package/skills/sendbird/scripts/client-guide.mjs +283 -0
- package/skills/sendbird/scripts/client-plugin-bridge.mjs +703 -0
- package/skills/sendbird-setup/SKILL.md +18 -0
- package/skills/sendbird-setup/agents/openai.yaml +4 -0
- package/skills/sendbird-setup/references/onboarding.md +73 -0
- package/skills/sendbird-setup/scripts/install-cli.mjs +447 -0
- package/skills/sendbird-setup/scripts/npm-run.mjs +34 -0
package/dist/oauth.js
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import { openBrowser as defaultOpenBrowser } from "./browser.js";
|
|
2
|
+
/** Browser OAuth for Gate's environment-bound Sendbird CLI public client. */
|
|
3
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
4
|
+
import { lstatSync, readFileSync, renameSync, writeFileSync, unlinkSync, } from "node:fs";
|
|
5
|
+
import { createServer } from "node:http";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { withCredentialLock } from "./oauth-lock.js";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { CliError, configDir, deleteSecret, getSecret, origins, request, setSecret, } from "./core.js";
|
|
10
|
+
import { verifySchema } from "./catalog.js";
|
|
11
|
+
import { callbackHtml } from "./oauth-callback.js";
|
|
12
|
+
const clientId = "sendbird-cli";
|
|
13
|
+
const scope = "cli:dashboard offline_access";
|
|
14
|
+
const credentialPrefix = "sendbird-oauth-v1:";
|
|
15
|
+
const Credential = z.object({
|
|
16
|
+
env: z.enum(["prod", "staging"]),
|
|
17
|
+
accessToken: z.string().min(1),
|
|
18
|
+
accessExpiresAt: z.number().int().positive(),
|
|
19
|
+
refreshToken: z.string().min(1).optional(),
|
|
20
|
+
refreshExpiresAt: z.number().int().positive().optional(),
|
|
21
|
+
scope: z.string().min(1),
|
|
22
|
+
});
|
|
23
|
+
const TokenResponse = z.object({
|
|
24
|
+
access_token: z.string().min(1),
|
|
25
|
+
token_type: z.string(),
|
|
26
|
+
expires_in: z.number().int().positive(),
|
|
27
|
+
scope: z.string().min(1),
|
|
28
|
+
refresh_token: z.string().min(1).optional(),
|
|
29
|
+
refresh_token_expires_in: z.number().int().nonnegative().optional(),
|
|
30
|
+
});
|
|
31
|
+
const Discovery = z.object({
|
|
32
|
+
issuer: z.string().url(),
|
|
33
|
+
authorization_endpoint: z.string().url(),
|
|
34
|
+
token_endpoint: z.string().url(),
|
|
35
|
+
revocation_endpoint: z.string().url(),
|
|
36
|
+
code_challenge_methods_supported: z.array(z.string()),
|
|
37
|
+
scopes_supported: z.array(z.string()),
|
|
38
|
+
});
|
|
39
|
+
export function isOAuthSecret(raw) {
|
|
40
|
+
return raw?.startsWith(credentialPrefix) ?? false;
|
|
41
|
+
}
|
|
42
|
+
function decode(raw) {
|
|
43
|
+
let value;
|
|
44
|
+
try {
|
|
45
|
+
value = JSON.parse(raw.slice(credentialPrefix.length));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
throw new CliError("E_AUTH", "Saved OAuth credentials are invalid; log in again", 4);
|
|
49
|
+
}
|
|
50
|
+
const parsed = Credential.safeParse(value);
|
|
51
|
+
if (!parsed.success)
|
|
52
|
+
throw new CliError("E_AUTH", "Saved OAuth credentials are invalid; log in again", 4);
|
|
53
|
+
return parsed.data;
|
|
54
|
+
}
|
|
55
|
+
function stored(name) {
|
|
56
|
+
const raw = getSecret(name);
|
|
57
|
+
return isOAuthSecret(raw) ? decode(raw) : undefined;
|
|
58
|
+
}
|
|
59
|
+
function save(name, credential) {
|
|
60
|
+
setSecret(name, credentialPrefix + JSON.stringify(Credential.parse(credential)));
|
|
61
|
+
}
|
|
62
|
+
function oauthError(status, body, operation) {
|
|
63
|
+
const rawError = body && typeof body === "object" && "error" in body
|
|
64
|
+
? String(body.error)
|
|
65
|
+
: undefined;
|
|
66
|
+
const error = rawError && /^[a-z_]{1,60}$/.test(rawError) ? rawError : undefined;
|
|
67
|
+
return new CliError(status === 400 && error === "invalid_grant" ? "E_AUTH" : "E_UPSTREAM", `${operation} failed (${status}${error ? `: ${error}` : ""})`, status === 400 || status === 401 ? 4 : 8);
|
|
68
|
+
}
|
|
69
|
+
async function formRequest(url, params, fetcher, operation, allowEmpty = false) {
|
|
70
|
+
let response;
|
|
71
|
+
try {
|
|
72
|
+
response = await fetcher(url, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: {
|
|
75
|
+
Accept: "application/json",
|
|
76
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
77
|
+
},
|
|
78
|
+
body: new URLSearchParams(params),
|
|
79
|
+
redirect: "error",
|
|
80
|
+
signal: AbortSignal.timeout(15_000),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
throw new CliError("E_NETWORK", `${operation} outcome is unknown; log in again`, 7);
|
|
85
|
+
}
|
|
86
|
+
let body;
|
|
87
|
+
try {
|
|
88
|
+
body = await response.json();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
if (response.ok && !allowEmpty)
|
|
92
|
+
throw new CliError("E_SCHEMA", `${operation} returned invalid JSON`, 8);
|
|
93
|
+
}
|
|
94
|
+
if (!response.ok)
|
|
95
|
+
throw oauthError(response.status, body, operation);
|
|
96
|
+
return body;
|
|
97
|
+
}
|
|
98
|
+
function parsePair(body, env, previous) {
|
|
99
|
+
const pair = TokenResponse.safeParse(body);
|
|
100
|
+
if (!pair.success || pair.data.token_type.toLowerCase() !== "bearer")
|
|
101
|
+
throw new CliError("E_SCHEMA", "Gate returned an invalid OAuth token response", 8);
|
|
102
|
+
if (!pair.data.scope.split(" ").includes("cli:dashboard"))
|
|
103
|
+
throw new CliError("E_AUTH", "Gate did not grant CLI Dashboard scope", 4);
|
|
104
|
+
if (previous && !pair.data.refresh_token)
|
|
105
|
+
throw new CliError("E_SCHEMA", "Gate refresh response omitted the rotated token", 8);
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
const refreshToken = pair.data.refresh_token ?? previous?.refreshToken;
|
|
108
|
+
const refreshExpiresAt = pair.data.refresh_token_expires_in !== undefined
|
|
109
|
+
? now + pair.data.refresh_token_expires_in * 1000
|
|
110
|
+
: previous?.refreshExpiresAt;
|
|
111
|
+
return {
|
|
112
|
+
env,
|
|
113
|
+
accessToken: pair.data.access_token,
|
|
114
|
+
accessExpiresAt: now + pair.data.expires_in * 1000,
|
|
115
|
+
refreshToken,
|
|
116
|
+
refreshExpiresAt,
|
|
117
|
+
scope: pair.data.scope,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function sameOrigin(url, origin) {
|
|
121
|
+
// Discovery.safeParse has already validated every endpoint URL.
|
|
122
|
+
return new URL(url).origin === origin;
|
|
123
|
+
}
|
|
124
|
+
async function discover(origin, fetcher) {
|
|
125
|
+
let response;
|
|
126
|
+
try {
|
|
127
|
+
response = await fetcher(`${origin}/.well-known/oauth-authorization-server`, {
|
|
128
|
+
redirect: "error",
|
|
129
|
+
signal: AbortSignal.timeout(15_000),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new CliError("E_NETWORK", "Could not discover Gate OAuth endpoints", 7);
|
|
134
|
+
}
|
|
135
|
+
if (!response.ok)
|
|
136
|
+
throw new CliError("E_AUTH", "Gate OAuth discovery is unavailable", 4);
|
|
137
|
+
const parsed = Discovery.safeParse(await response.json());
|
|
138
|
+
if (!parsed.success ||
|
|
139
|
+
parsed.data.issuer !== origin ||
|
|
140
|
+
![
|
|
141
|
+
parsed.data.authorization_endpoint,
|
|
142
|
+
parsed.data.token_endpoint,
|
|
143
|
+
parsed.data.revocation_endpoint,
|
|
144
|
+
].every((url) => sameOrigin(url, origin)) ||
|
|
145
|
+
!parsed.data.code_challenge_methods_supported.includes("S256") ||
|
|
146
|
+
!parsed.data.scopes_supported.includes("cli:dashboard"))
|
|
147
|
+
throw new CliError("E_AUTH", "Gate has not enabled CLI OAuth for this environment", 4);
|
|
148
|
+
return parsed.data;
|
|
149
|
+
}
|
|
150
|
+
function matchesState(expected, actual) {
|
|
151
|
+
const a = Buffer.from(expected);
|
|
152
|
+
const b = Buffer.from(actual);
|
|
153
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
154
|
+
}
|
|
155
|
+
async function listenForCode(state, timeoutMs) {
|
|
156
|
+
let resolveCode;
|
|
157
|
+
let rejectCode;
|
|
158
|
+
let completed = false;
|
|
159
|
+
const code = new Promise((resolve, reject) => {
|
|
160
|
+
resolveCode = resolve;
|
|
161
|
+
rejectCode = reject;
|
|
162
|
+
});
|
|
163
|
+
const sockets = new Set();
|
|
164
|
+
const server = createServer((req, res) => {
|
|
165
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
166
|
+
res.setHeader("Cache-Control", "no-store");
|
|
167
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
168
|
+
res.setHeader("Referrer-Policy", "no-referrer");
|
|
169
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
170
|
+
res.setHeader("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'");
|
|
171
|
+
if (completed ||
|
|
172
|
+
req.method !== "GET" ||
|
|
173
|
+
url.pathname !== "/oauth/callback") {
|
|
174
|
+
res.writeHead(404).end(callbackHtml("invalid"));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (!matchesState(state, url.searchParams.get("state") ?? "")) {
|
|
178
|
+
res.writeHead(400).end(callbackHtml("invalid"));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
completed = true;
|
|
182
|
+
if (url.searchParams.get("error")) {
|
|
183
|
+
res
|
|
184
|
+
.writeHead(200)
|
|
185
|
+
.end(callbackHtml("declined"), () => rejectCode(new CliError("E_AUTH", "CLI authorization was declined", 4)));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const value = url.searchParams.get("code");
|
|
189
|
+
if (!value) {
|
|
190
|
+
res
|
|
191
|
+
.writeHead(400)
|
|
192
|
+
.end(callbackHtml("invalid"), () => rejectCode(new CliError("E_AUTH", "OAuth callback had no code", 4)));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
res.writeHead(200).end(callbackHtml("received"), () => resolveCode(value));
|
|
196
|
+
});
|
|
197
|
+
server.on("connection", (socket) => {
|
|
198
|
+
sockets.add(socket);
|
|
199
|
+
socket.on("close", () => sockets.delete(socket));
|
|
200
|
+
});
|
|
201
|
+
await new Promise((resolve, reject) => {
|
|
202
|
+
server.once("error", reject);
|
|
203
|
+
server.listen(0, "127.0.0.1", resolve);
|
|
204
|
+
});
|
|
205
|
+
const address = server.address();
|
|
206
|
+
if (!address || typeof address === "string")
|
|
207
|
+
throw new CliError("E_NETWORK", "Could not bind OAuth callback", 7);
|
|
208
|
+
const callback = `http://127.0.0.1:${address.port}/oauth/callback`;
|
|
209
|
+
const close = () => {
|
|
210
|
+
if (server.listening)
|
|
211
|
+
server.close();
|
|
212
|
+
// A browser may leave a keep-alive or incomplete request open. Such a
|
|
213
|
+
// socket must not keep the one-shot CLI process alive after OAuth ends.
|
|
214
|
+
for (const socket of sockets)
|
|
215
|
+
socket.destroy();
|
|
216
|
+
};
|
|
217
|
+
return {
|
|
218
|
+
callback,
|
|
219
|
+
wait: async () => {
|
|
220
|
+
let timeout;
|
|
221
|
+
try {
|
|
222
|
+
return await Promise.race([
|
|
223
|
+
code,
|
|
224
|
+
new Promise((_, reject) => {
|
|
225
|
+
timeout = setTimeout(() => reject(new CliError("E_AUTH", "Browser login timed out", 4)), timeoutMs);
|
|
226
|
+
}),
|
|
227
|
+
]);
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
clearTimeout(timeout);
|
|
231
|
+
close();
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
close,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function generationPath(name) {
|
|
238
|
+
return join(configDir(), `oauth-${Buffer.from(name).toString("hex")}.generation`);
|
|
239
|
+
}
|
|
240
|
+
function generation(name) {
|
|
241
|
+
const path = generationPath(name);
|
|
242
|
+
let stat;
|
|
243
|
+
try {
|
|
244
|
+
stat = lstatSync(path);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
if (error.code === "ENOENT")
|
|
248
|
+
return "";
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
252
|
+
throw new CliError("E_SECRET_STORE", "OAuth generation must be a regular file", 4);
|
|
253
|
+
const value = readFileSync(path, "utf8");
|
|
254
|
+
if (/^[a-f0-9]{32}$/.test(value))
|
|
255
|
+
return value;
|
|
256
|
+
// Callers hold the credential lock. Replacing a corrupt non-secret marker
|
|
257
|
+
// also invalidates approvals that captured the previous generation.
|
|
258
|
+
return writeGeneration(name);
|
|
259
|
+
}
|
|
260
|
+
function advanceGeneration(name) {
|
|
261
|
+
generation(name); // Preserve the regular-file/symlink checks.
|
|
262
|
+
return writeGeneration(name);
|
|
263
|
+
}
|
|
264
|
+
function writeGeneration(name) {
|
|
265
|
+
const path = generationPath(name);
|
|
266
|
+
const value = randomBytes(16).toString("hex");
|
|
267
|
+
const tmp = `${path}.${process.pid}.${randomBytes(4).toString("hex")}.tmp`;
|
|
268
|
+
try {
|
|
269
|
+
writeFileSync(tmp, value, {
|
|
270
|
+
mode: 0o600,
|
|
271
|
+
flag: "wx",
|
|
272
|
+
});
|
|
273
|
+
renameSync(tmp, path);
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
try {
|
|
278
|
+
unlinkSync(tmp);
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
/* Non-secret temporary marker cleanup. */
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
export async function loginOAuth(name, env, options = {}) {
|
|
286
|
+
// Check the credential store before opening a browser or exchanging a code.
|
|
287
|
+
// In particular, a legacy plaintext file must not strand a fresh grant.
|
|
288
|
+
const expectedGeneration = await withCredentialLock(name, async () => {
|
|
289
|
+
stored(name);
|
|
290
|
+
return generation(name);
|
|
291
|
+
});
|
|
292
|
+
const fetcher = options.fetcher ?? fetch;
|
|
293
|
+
const origin = origins[env];
|
|
294
|
+
const endpoints = await discover(origin, fetcher);
|
|
295
|
+
const state = randomBytes(32).toString("base64url");
|
|
296
|
+
const verifier = randomBytes(32).toString("base64url");
|
|
297
|
+
const challenge = createHash("sha256").update(verifier).digest("base64url");
|
|
298
|
+
const listener = await listenForCode(state, options.timeoutMs ?? 180_000);
|
|
299
|
+
try {
|
|
300
|
+
const url = new URL(endpoints.authorization_endpoint);
|
|
301
|
+
for (const [key, value] of Object.entries({
|
|
302
|
+
response_type: "code",
|
|
303
|
+
client_id: clientId,
|
|
304
|
+
redirect_uri: listener.callback,
|
|
305
|
+
code_challenge: challenge,
|
|
306
|
+
code_challenge_method: "S256",
|
|
307
|
+
state,
|
|
308
|
+
scope,
|
|
309
|
+
}))
|
|
310
|
+
url.searchParams.set(key, value);
|
|
311
|
+
const entryUrl = options.entry === "signup"
|
|
312
|
+
? (() => {
|
|
313
|
+
const signup = new URL(env === "prod"
|
|
314
|
+
? "https://dashboard.sendbird.com/auth/signup"
|
|
315
|
+
: "https://dashboard-dev.sendbird.com/auth/signup");
|
|
316
|
+
signup.searchParams.set("next", url.toString());
|
|
317
|
+
return signup.toString();
|
|
318
|
+
})()
|
|
319
|
+
: url.toString();
|
|
320
|
+
options.onUrl?.(entryUrl);
|
|
321
|
+
(options.openBrowser ?? defaultOpenBrowser)(entryUrl);
|
|
322
|
+
const authorizationCode = await listener.wait();
|
|
323
|
+
const pair = parsePair(await formRequest(endpoints.token_endpoint, {
|
|
324
|
+
grant_type: "authorization_code",
|
|
325
|
+
client_id: clientId,
|
|
326
|
+
code: authorizationCode,
|
|
327
|
+
code_verifier: verifier,
|
|
328
|
+
redirect_uri: listener.callback,
|
|
329
|
+
}, fetcher, "OAuth code exchange"), env);
|
|
330
|
+
// Gate verify2 currently sends Set-Cookie for Bearer callers. Never persist it.
|
|
331
|
+
let identity;
|
|
332
|
+
try {
|
|
333
|
+
const raw = await request({ origin, env, bearer: pair.accessToken, fetch: fetcher }, {
|
|
334
|
+
method: "GET",
|
|
335
|
+
path: "/dashboard/auth/verify2/",
|
|
336
|
+
});
|
|
337
|
+
const parsed = verifySchema.safeParse(raw);
|
|
338
|
+
if (!parsed.success)
|
|
339
|
+
throw new CliError("E_SCHEMA", "OAuth identity response has changed", 8);
|
|
340
|
+
identity = parsed.data;
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
await revokePair(pair, fetcher);
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
await withCredentialLock(name, async () => {
|
|
348
|
+
if (generation(name) !== expectedGeneration)
|
|
349
|
+
throw new CliError("E_AUTH", "Login was superseded by another authentication operation; start a new login", 4);
|
|
350
|
+
const current = stored(name);
|
|
351
|
+
try {
|
|
352
|
+
// Keep the old remote pair usable until the replacement is stored.
|
|
353
|
+
save(name, pair);
|
|
354
|
+
advanceGeneration(name);
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
try {
|
|
358
|
+
const after = stored(name);
|
|
359
|
+
const oldStillStored = current &&
|
|
360
|
+
after &&
|
|
361
|
+
current.accessToken === after.accessToken &&
|
|
362
|
+
current.refreshToken === after.refreshToken;
|
|
363
|
+
if (!oldStillStored) {
|
|
364
|
+
if (current)
|
|
365
|
+
save(name, current);
|
|
366
|
+
else
|
|
367
|
+
deleteSecret(name);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
try {
|
|
372
|
+
deleteSecret(name);
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
/* Preserve the storage failure. */
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
throw error;
|
|
379
|
+
}
|
|
380
|
+
if (current)
|
|
381
|
+
await revokePair(current, fetcher);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
await revokePair(pair, fetcher);
|
|
386
|
+
throw error;
|
|
387
|
+
}
|
|
388
|
+
return identity;
|
|
389
|
+
}
|
|
390
|
+
finally {
|
|
391
|
+
listener.close();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async function refresh(name, fetcher, expectedEnv) {
|
|
395
|
+
return withCredentialLock(name, async () => {
|
|
396
|
+
const current = stored(name);
|
|
397
|
+
if (!current)
|
|
398
|
+
throw new CliError("E_AUTH", "OAuth login required", 4);
|
|
399
|
+
checkEnvironment(current, expectedEnv);
|
|
400
|
+
if (current.accessExpiresAt > Date.now() + 10_000)
|
|
401
|
+
return current.accessToken;
|
|
402
|
+
if (!current.refreshToken ||
|
|
403
|
+
(current.refreshExpiresAt !== undefined &&
|
|
404
|
+
current.refreshExpiresAt <= Date.now()))
|
|
405
|
+
throw new CliError("E_AUTH", "OAuth grant expired; log in again", 4);
|
|
406
|
+
let pair;
|
|
407
|
+
try {
|
|
408
|
+
pair = parsePair(await formRequest(`${origins[current.env]}/oauth/token`, {
|
|
409
|
+
grant_type: "refresh_token",
|
|
410
|
+
client_id: clientId,
|
|
411
|
+
refresh_token: current.refreshToken,
|
|
412
|
+
}, fetcher, "OAuth refresh"), current.env, current);
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
// A one-time refresh may have been consumed even if the response failed.
|
|
416
|
+
// Never retry the same token or claim the prior credential is usable.
|
|
417
|
+
deleteSecret(name);
|
|
418
|
+
throw error;
|
|
419
|
+
}
|
|
420
|
+
try {
|
|
421
|
+
save(name, pair);
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
// The old refresh was consumed. Neither pair is a usable fallback.
|
|
425
|
+
try {
|
|
426
|
+
await revokePair(pair, fetcher);
|
|
427
|
+
}
|
|
428
|
+
finally {
|
|
429
|
+
deleteSecret(name);
|
|
430
|
+
}
|
|
431
|
+
throw error;
|
|
432
|
+
}
|
|
433
|
+
return pair.accessToken;
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
function checkEnvironment(credential, expectedEnv) {
|
|
437
|
+
if (expectedEnv && credential.env !== expectedEnv)
|
|
438
|
+
throw new CliError("E_AUTH", "Saved OAuth credentials belong to a different environment; log in to this profile again", 4);
|
|
439
|
+
}
|
|
440
|
+
export async function oauthAccessToken(name, fetcher = fetch, expectedEnv) {
|
|
441
|
+
const current = stored(name);
|
|
442
|
+
if (!current)
|
|
443
|
+
throw new CliError("E_AUTH", "OAuth login required", 4);
|
|
444
|
+
checkEnvironment(current, expectedEnv);
|
|
445
|
+
if (current.accessExpiresAt > Date.now() + 10_000)
|
|
446
|
+
return current.accessToken;
|
|
447
|
+
return refresh(name, fetcher, expectedEnv);
|
|
448
|
+
}
|
|
449
|
+
async function revokePair(current, fetcher) {
|
|
450
|
+
let remoteRevocation = "complete";
|
|
451
|
+
for (const [token, hint] of [
|
|
452
|
+
[current.refreshToken, "refresh_token"],
|
|
453
|
+
[current.accessToken, "access_token"],
|
|
454
|
+
]) {
|
|
455
|
+
if (!token)
|
|
456
|
+
continue;
|
|
457
|
+
try {
|
|
458
|
+
await formRequest(`${origins[current.env]}/oauth/revoke`, {
|
|
459
|
+
client_id: clientId,
|
|
460
|
+
token,
|
|
461
|
+
token_type_hint: hint,
|
|
462
|
+
}, fetcher, "OAuth revoke", true);
|
|
463
|
+
}
|
|
464
|
+
catch {
|
|
465
|
+
remoteRevocation = "unknown";
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return remoteRevocation;
|
|
469
|
+
}
|
|
470
|
+
export async function logoutOAuth(name, fetcher = fetch) {
|
|
471
|
+
return withCredentialLock(name, async () => {
|
|
472
|
+
const raw = getSecret(name);
|
|
473
|
+
// Also cancel a browser login waiting for approval, even with no tokens.
|
|
474
|
+
advanceGeneration(name);
|
|
475
|
+
let current;
|
|
476
|
+
try {
|
|
477
|
+
current = isOAuthSecret(raw) ? decode(raw) : undefined;
|
|
478
|
+
}
|
|
479
|
+
catch {
|
|
480
|
+
deleteSecret(name);
|
|
481
|
+
return { remote_revocation: "unknown" };
|
|
482
|
+
}
|
|
483
|
+
if (!current) {
|
|
484
|
+
if (raw)
|
|
485
|
+
deleteSecret(name);
|
|
486
|
+
return { remote_revocation: "not_applicable" };
|
|
487
|
+
}
|
|
488
|
+
const remoteRevocation = await revokePair(current, fetcher);
|
|
489
|
+
deleteSecret(name);
|
|
490
|
+
return { remote_revocation: remoteRevocation };
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
|