@michael-joseph-miller/ant-bot 0.3.0 → 0.3.1
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/CHANGELOG.md +13 -0
- package/README.md +3 -3
- package/dist/server.js +41 -11
- package/dist/server.js.map +2 -2
- package/package.json +1 -1
- package/web/dist/assets/{index-uIFP-bJK.js → index-B74AZxue.js} +1 -1
- package/web/dist/index.html +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to ant-bot are recorded here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
|
|
5
5
|
[semantic versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.3.1] — 2026-08-24
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **Sign-in accepts a client secret.** Google's "Web application" OAuth clients authenticate at
|
|
12
|
+
the token endpoint, so a client ID alone got as far as the consent screen and then failed with
|
|
13
|
+
the provider's own `client_secret is missing`. Both the CLI (`--client-secret`) and the
|
|
14
|
+
Connectors screen now take one, and ant-bot explains what is needed rather than passing that
|
|
15
|
+
message through unhelpfully.
|
|
16
|
+
- **Client credentials are remembered.** They are registered once with a provider and outlive any
|
|
17
|
+
token, so they are stored in the keychain under their own key — a second sign-in, after an
|
|
18
|
+
expiry or a failed exchange, needs no flags.
|
|
19
|
+
|
|
7
20
|
## [0.3.0] — 2026-08-24
|
|
8
21
|
|
|
9
22
|
### Added
|
package/README.md
CHANGED
|
@@ -280,10 +280,10 @@ Current totals, as run against this checkout:
|
|
|
280
280
|
| Package | Test files | Tests |
|
|
281
281
|
|---|---|---|
|
|
282
282
|
| `@antbot/contract` | 1 | 34 |
|
|
283
|
-
| `@antbot/daemon` | 25 |
|
|
284
|
-
| `@antbot/ui` | 9 |
|
|
283
|
+
| `@antbot/daemon` | 25 | 575 |
|
|
284
|
+
| `@antbot/ui` | 9 | 92 |
|
|
285
285
|
| `@antbot/cli` | 8 | 140 |
|
|
286
|
-
| **Total** | **43** | **
|
|
286
|
+
| **Total** | **43** | **841** |
|
|
287
287
|
|
|
288
288
|
## Status / not built
|
|
289
289
|
|
package/dist/server.js
CHANGED
|
@@ -2306,6 +2306,7 @@ async function refreshTokens(tokens, now2 = Date.now()) {
|
|
|
2306
2306
|
// daemon/src/connectors/auth.ts
|
|
2307
2307
|
var log7 = logger("connector-auth");
|
|
2308
2308
|
var tokenSecretName = (connectorName) => `antbot:oauth:${connectorName}`;
|
|
2309
|
+
var clientSecretName = (connectorName) => `antbot:oauth-client:${connectorName}`;
|
|
2309
2310
|
var redirectUri = (port) => `http://127.0.0.1:${port}/api/connectors/oauth/callback`;
|
|
2310
2311
|
var LOGIN_TTL_MS = 10 * 60 * 1e3;
|
|
2311
2312
|
var ConnectorAuthService = class {
|
|
@@ -2337,6 +2338,20 @@ var ConnectorAuthService = class {
|
|
|
2337
2338
|
async signOut(connectorName) {
|
|
2338
2339
|
await this.secrets.remove(tokenSecretName(connectorName));
|
|
2339
2340
|
}
|
|
2341
|
+
/** Forget the tokens *and* the registered client. Used when the credentials themselves are wrong. */
|
|
2342
|
+
async forgetClient(connectorName) {
|
|
2343
|
+
await this.secrets.remove(clientSecretName(connectorName));
|
|
2344
|
+
}
|
|
2345
|
+
async readClient(connectorName) {
|
|
2346
|
+
const key = clientSecretName(connectorName);
|
|
2347
|
+
const found = (await this.secrets.resolve([key])).get(key);
|
|
2348
|
+
if (!found) return null;
|
|
2349
|
+
try {
|
|
2350
|
+
return JSON.parse(found);
|
|
2351
|
+
} catch {
|
|
2352
|
+
return null;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2340
2355
|
/**
|
|
2341
2356
|
* Begin a sign-in. Returns the URL the human must open.
|
|
2342
2357
|
*
|
|
@@ -2350,8 +2365,9 @@ var ConnectorAuthService = class {
|
|
|
2350
2365
|
}
|
|
2351
2366
|
const discovery = await discoverAuth(connector.config.url);
|
|
2352
2367
|
const redirect = redirectUri(this.port);
|
|
2353
|
-
|
|
2354
|
-
let
|
|
2368
|
+
const remembered = await this.readClient(connector.name);
|
|
2369
|
+
let clientId = opts.clientId ?? remembered?.clientId;
|
|
2370
|
+
let clientSecret = opts.clientSecret ?? (opts.clientId ? void 0 : remembered?.clientSecret);
|
|
2355
2371
|
if (!clientId && discovery.authServer.registrationEndpoint) {
|
|
2356
2372
|
const registered = await registerClient(discovery.authServer.registrationEndpoint, redirect);
|
|
2357
2373
|
clientId = registered?.clientId;
|
|
@@ -2362,6 +2378,9 @@ var ConnectorAuthService = class {
|
|
|
2362
2378
|
`${new URL(discovery.authServer.authorizationEndpoint).host} does not support automatic app registration, so it needs a client ID you create yourself. Register one with that provider, add "${redirect}" as an authorised redirect URI, and pass the client ID with --client-id.`
|
|
2363
2379
|
);
|
|
2364
2380
|
}
|
|
2381
|
+
if (opts.clientId || opts.clientSecret || !remembered) {
|
|
2382
|
+
await this.secrets.set(clientSecretName(connector.name), JSON.stringify({ clientId, clientSecret }));
|
|
2383
|
+
}
|
|
2365
2384
|
const pkce = createPkce();
|
|
2366
2385
|
const state = crypto2.randomBytes(16).toString("base64url");
|
|
2367
2386
|
this.pending.set(state, {
|
|
@@ -2394,15 +2413,26 @@ var ConnectorAuthService = class {
|
|
|
2394
2413
|
const p = this.pending.get(state);
|
|
2395
2414
|
if (!p) throw new OAuthError("This sign-in link is no longer valid. Start the sign-in again.");
|
|
2396
2415
|
this.pending.delete(state);
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2416
|
+
let tokens;
|
|
2417
|
+
try {
|
|
2418
|
+
tokens = await exchangeCode({
|
|
2419
|
+
tokenEndpoint: p.tokenEndpoint,
|
|
2420
|
+
code,
|
|
2421
|
+
verifier: p.verifier,
|
|
2422
|
+
clientId: p.clientId,
|
|
2423
|
+
clientSecret: p.clientSecret,
|
|
2424
|
+
redirectUri: p.redirectUri,
|
|
2425
|
+
resource: p.resource
|
|
2426
|
+
});
|
|
2427
|
+
} catch (err) {
|
|
2428
|
+
const message = err.message;
|
|
2429
|
+
if (/client_secret/i.test(message)) {
|
|
2430
|
+
throw new OAuthError(
|
|
2431
|
+
`This provider requires a client secret as well as a client ID. Add the secret from the same OAuth client (in Google's console: the client's "Client secret") and sign in again.`
|
|
2432
|
+
);
|
|
2433
|
+
}
|
|
2434
|
+
throw err;
|
|
2435
|
+
}
|
|
2406
2436
|
await this.write(p.connectorName, tokens);
|
|
2407
2437
|
log7.info(`connector "${p.connectorName}" signed in`);
|
|
2408
2438
|
return { connectorId: p.connectorId, connectorName: p.connectorName };
|