latchkey 3.5.0 → 3.7.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.
Files changed (47) hide show
  1. package/dist/skills/generic/latchkey/SKILL.md +1 -1
  2. package/dist/skills/openclaw/latchkey/SKILL.md +1 -1
  3. package/dist/src/apiCredentials/serialization.d.ts +12 -0
  4. package/dist/src/apiCredentials/serialization.d.ts.map +1 -1
  5. package/dist/src/apiCredentials/serialization.js +7 -0
  6. package/dist/src/apiCredentials/serialization.js.map +1 -1
  7. package/dist/src/oauthUtils.d.ts +2 -2
  8. package/dist/src/oauthUtils.d.ts.map +1 -1
  9. package/dist/src/oauthUtils.js +36 -15
  10. package/dist/src/oauthUtils.js.map +1 -1
  11. package/dist/src/serviceRegistry.d.ts.map +1 -1
  12. package/dist/src/serviceRegistry.js +4 -1
  13. package/dist/src/serviceRegistry.js.map +1 -1
  14. package/dist/src/services/fastmail-dav.d.ts +55 -0
  15. package/dist/src/services/fastmail-dav.d.ts.map +1 -0
  16. package/dist/src/services/fastmail-dav.js +98 -0
  17. package/dist/src/services/fastmail-dav.js.map +1 -0
  18. package/dist/src/services/fastmail.d.ts +79 -0
  19. package/dist/src/services/fastmail.d.ts.map +1 -0
  20. package/dist/src/services/fastmail.js +298 -0
  21. package/dist/src/services/fastmail.js.map +1 -0
  22. package/dist/src/services/google/gmail.d.ts.map +1 -1
  23. package/dist/src/services/google/gmail.js +6 -1
  24. package/dist/src/services/google/gmail.js.map +1 -1
  25. package/dist/src/services/index.d.ts +3 -0
  26. package/dist/src/services/index.d.ts.map +1 -1
  27. package/dist/src/services/index.js +3 -0
  28. package/dist/src/services/index.js.map +1 -1
  29. package/dist/src/services/tailscale.d.ts +74 -0
  30. package/dist/src/services/tailscale.d.ts.map +1 -0
  31. package/dist/src/services/tailscale.js +221 -0
  32. package/dist/src/services/tailscale.js.map +1 -0
  33. package/dist/src/sharedOperations.d.ts +1 -1
  34. package/dist/src/sharedOperations.d.ts.map +1 -1
  35. package/dist/src/sharedOperations.js +12 -1
  36. package/dist/src/sharedOperations.js.map +1 -1
  37. package/dist/src/version.d.ts +1 -1
  38. package/dist/src/version.js +1 -1
  39. package/dist/tests/serviceRegistry.test.js +32 -1
  40. package/dist/tests/serviceRegistry.test.js.map +1 -1
  41. package/dist/tests/servicesAgainstRecordings.test.js +12 -3
  42. package/dist/tests/servicesAgainstRecordings.test.js.map +1 -1
  43. package/dist/tests/tailscale.test.d.ts +2 -0
  44. package/dist/tests/tailscale.test.d.ts.map +1 -0
  45. package/dist/tests/tailscale.test.js +79 -0
  46. package/dist/tests/tailscale.test.js.map +1 -0
  47. package/package.json +2 -2
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Fastmail service implementation.
3
+ *
4
+ * Fastmail's JMAP API is an OAuth 2.1 protected resource: it advertises an
5
+ * authorization server at `https://api.fastmail.com` (RFC 8414 metadata at
6
+ * `/.well-known/oauth-authorization-server`) supporting dynamic client
7
+ * registration, PKCE (S256) and refresh tokens, with public clients
8
+ * (`token_endpoint_auth_method: none`). So no API token has to be created by
9
+ * hand in the account's settings and pasted in — `latchkey auth browser
10
+ * fastmail` is enough.
11
+ */
12
+ import { z } from 'zod';
13
+ import { OAuthCredentials } from '../apiCredentials/base.js';
14
+ import { DEFAULT_ACCOUNT, fetchAccountFromEndpoint, tryParseJson, } from '../apiCredentials/account.js';
15
+ import { runCapturedAsync } from '../curl.js';
16
+ import { exchangeCodeForTokens, generateCodeChallenge, generateCodeVerifier, refreshAccessToken, startOAuthCallbackServer, } from '../oauthUtils.js';
17
+ import { Service, ServiceSession, LoginFailedError, LoginCancelledError, buildPreparedCredentials, isBrowserClosedError, } from './core/base.js';
18
+ /**
19
+ * JSON accepted by `latchkey auth prepare fastmail`: an OAuth client id to
20
+ * reuse instead of registering a new client dynamically. Fastmail issues
21
+ * public clients, so no secret is needed. `.strict()` rejects unknown keys so
22
+ * typos are reported instead of silently ignored.
23
+ */
24
+ export const FastmailPrepareInputSchema = z
25
+ .object({
26
+ clientId: z.string().min(1),
27
+ })
28
+ .strict();
29
+ // The session document, requested directly. Not `/.well-known/jmap`: that
30
+ // 302s to this URL on a *different* host, and curl drops the Authorization
31
+ // header across a cross-host redirect, so following it reports a missing
32
+ // header even when the credential is fine.
33
+ const SESSION_ENDPOINT = 'https://api.fastmail.com/jmap/session';
34
+ const REGISTRATION_ENDPOINT = 'https://api.fastmail.com/oauth/register';
35
+ const AUTHORIZATION_ENDPOINT = 'https://api.fastmail.com/oauth/authorize';
36
+ // Named `/oauth/refresh` rather than `/oauth/token`, but this is the
37
+ // `token_endpoint` of Fastmail's authorization server metadata: it serves both
38
+ // the authorization_code exchange and the refresh_token grant.
39
+ const TOKEN_ENDPOINT = 'https://api.fastmail.com/oauth/refresh';
40
+ /**
41
+ * RFC 8707 resource indicator, required by Fastmail: an authorization request
42
+ * that does not name the resource it is for is refused with `invalid_target`.
43
+ * This is the `resource` of the protected-resource metadata at
44
+ * `/.well-known/oauth-protected-resource/jmap/session`, and it is what scopes
45
+ * the JMAP capabilities to. Fastmail publishes a second, unrelated resource for
46
+ * its MCP endpoint (`https://api.fastmail.com/mcp`) with its own scope; naming
47
+ * the wrong one here would yield tokens JMAP will not accept.
48
+ */
49
+ const JMAP_RESOURCE = 'https://api.fastmail.com/jmap/session';
50
+ /**
51
+ * One service carries all three JMAP scopes rather than splitting into
52
+ * per-capability services the way the Google ones do. Google's products are
53
+ * separate APIs on separate hosts, so a service each disambiguates cleanly;
54
+ * Fastmail's are one JMAP session behind one host, so sibling services would
55
+ * all match the same URLs and a request could pick whichever credential
56
+ * happened to be registered first — including one lacking the needed scope.
57
+ *
58
+ * Mail plus a refresh token. Fastmail also offers `…scope:contacts` and
59
+ * `…scope:calendars`, which JMAP exposes through the same session document —
60
+ * add them here if latchkey grows callers that need those capabilities, but
61
+ * asking for them today would over-request on the consent screen.
62
+ *
63
+ * These are the names the authorization server's own metadata advertises, and
64
+ * the only ones its registration endpoint accepts. Fastmail's developer docs
65
+ * list a different set (`urn:ietf:params:jmap:core`, `urn:ietf:params:jmap:mail`,
66
+ * …) which apply to clients registered by hand with Fastmail's partnerships
67
+ * team; passing those to dynamic registration fails outright.
68
+ *
69
+ * The same string is sent twice: once when registering the client, and again on
70
+ * the authorization request. They have to agree — see {@link registerClient}.
71
+ *
72
+ * These grant read AND write: Fastmail publishes no read-only OAuth scope, and
73
+ * its registration endpoint rejects every `:readonly` variant. A read-only
74
+ * credential has to be a hand-made API token ("Read-only access" on the API
75
+ * token screen) supplied with `latchkey auth set`, which this service also
76
+ * accepts.
77
+ */
78
+ const OAUTH_SCOPES = 'urn:ietf:params:oauth:scope:mail ' +
79
+ 'urn:ietf:params:oauth:scope:contacts ' +
80
+ 'urn:ietf:params:oauth:scope:calendars ' +
81
+ 'offline_access';
82
+ const LOGIN_TIMEOUT_MS = 120000;
83
+ /**
84
+ * Register a public OAuth client via RFC 7591 dynamic client registration.
85
+ *
86
+ * Fastmail normalizes a loopback `redirect_uri` by dropping the port (RFC 8252
87
+ * §7.3 lets a native client's loopback port vary), so one registration keeps
88
+ * working across the ephemeral ports {@link startOAuthCallbackServer} picks.
89
+ */
90
+ async function registerClient(redirectUri, clientName) {
91
+ const body = JSON.stringify({
92
+ client_name: clientName,
93
+ redirect_uris: [redirectUri],
94
+ grant_types: ['authorization_code', 'refresh_token'],
95
+ response_types: ['code'],
96
+ token_endpoint_auth_method: 'none',
97
+ // Required. Fastmail records the scopes at registration time and rejects an
98
+ // authorization request asking for anything outside them ("This MUST be a
99
+ // subset of the scopes registered for the client"). Omitting this registers
100
+ // the client with an empty scope, and every later authorize call comes back
101
+ // to the callback with an error and no code.
102
+ scope: OAUTH_SCOPES,
103
+ });
104
+ const result = await runCapturedAsync(['-s', '-X', 'POST', '-H', 'Content-Type: application/json', '-d', body, REGISTRATION_ENDPOINT], 30);
105
+ if (result.returncode !== 0) {
106
+ throw new LoginFailedError(`Failed to register OAuth client: ${result.stderr}`);
107
+ }
108
+ try {
109
+ const response = JSON.parse(result.stdout);
110
+ if (!response.client_id) {
111
+ throw new LoginFailedError(`Client registration response missing client_id: ${result.stdout}`);
112
+ }
113
+ return response;
114
+ }
115
+ catch (error) {
116
+ if (error instanceof LoginFailedError) {
117
+ throw error;
118
+ }
119
+ throw new LoginFailedError(`Failed to parse client registration response: ${error instanceof Error ? error.message : String(error)}`);
120
+ }
121
+ }
122
+ /**
123
+ * Absolute expiry for an `expires_in`, or undefined when the server did not send
124
+ * a usable one. `OAuthCredentials.accessTokenExpiresAt` is optional and
125
+ * `isExpired()` answers "unknown" without it, so omitting it degrades to
126
+ * refresh-on-failure. Computing it blindly would turn a missing value into
127
+ * `new Date(NaN).toISOString()`, which throws RangeError and loses the tokens
128
+ * that were just successfully obtained.
129
+ */
130
+ function expiryFromExpiresIn(expiresIn) {
131
+ if (typeof expiresIn !== 'number' || !Number.isFinite(expiresIn) || expiresIn <= 0) {
132
+ return undefined;
133
+ }
134
+ return new Date(Date.now() + expiresIn * 1000).toISOString();
135
+ }
136
+ /**
137
+ * The JMAP session document names the authenticated account in `username`
138
+ * (RFC 8620 §2), which for Fastmail is the account's e-mail address.
139
+ */
140
+ function parseAccountFromSession(responseBody) {
141
+ const session = tryParseJson(responseBody);
142
+ return session?.username ?? null;
143
+ }
144
+ class FastmailSession extends ServiceSession {
145
+ onResponse(_response) {
146
+ // Not used — login detection is via OAuth callback, not response inspection.
147
+ }
148
+ isLoginComplete() {
149
+ // Not used — we override login() entirely.
150
+ return false;
151
+ }
152
+ finalizeCredentials(_browser, _context, _oldCredentials) {
153
+ // Not used — we override login() entirely.
154
+ return Promise.resolve(null);
155
+ }
156
+ async login(encryptedStorage, launchOptions = {}, oldCredentials) {
157
+ const { withTempBrowserContext } = await import('../playwrightUtils.js');
158
+ return withTempBrowserContext(encryptedStorage, launchOptions, async ({ context }) => {
159
+ const page = await context.newPage();
160
+ const abortController = new AbortController();
161
+ const closeHandler = () => {
162
+ abortController.abort();
163
+ };
164
+ page.on('close', closeHandler);
165
+ context.on('close', closeHandler);
166
+ try {
167
+ // 1. Start OAuth callback server
168
+ const { port, codePromise } = await startOAuthCallbackServer(LOGIN_TIMEOUT_MS, abortController.signal);
169
+ const redirectUri = `http://localhost:${port.toString()}/oauth2callback`;
170
+ // 2. Register client or reuse existing client_id.
171
+ //
172
+ // Fastmail fixes a client's scopes at registration, so reusing a stored
173
+ // client id pins the scopes granted the first time. If OAUTH_SCOPES ever
174
+ // widens, an existing user's next login is refused for asking outside
175
+ // the old client's scopes, and `latchkey auth clear fastmail --all`
176
+ // (which drops the stored client id) is the way out.
177
+ let clientId;
178
+ if (oldCredentials instanceof OAuthCredentials && oldCredentials.clientId) {
179
+ clientId = oldCredentials.clientId;
180
+ }
181
+ else {
182
+ const registration = await registerClient(redirectUri, this.generateAppName());
183
+ clientId = registration.client_id;
184
+ }
185
+ // 3. Generate PKCE verifier/challenge
186
+ const codeVerifier = generateCodeVerifier();
187
+ const codeChallenge = generateCodeChallenge(codeVerifier);
188
+ // 4. Open browser to authorization URL
189
+ const authUrl = new URL(AUTHORIZATION_ENDPOINT);
190
+ authUrl.searchParams.set('client_id', clientId);
191
+ authUrl.searchParams.set('redirect_uri', redirectUri);
192
+ authUrl.searchParams.set('response_type', 'code');
193
+ authUrl.searchParams.set('scope', OAUTH_SCOPES);
194
+ authUrl.searchParams.set('resource', JMAP_RESOURCE);
195
+ authUrl.searchParams.set('code_challenge', codeChallenge);
196
+ authUrl.searchParams.set('code_challenge_method', 'S256');
197
+ await page.goto(authUrl.toString());
198
+ // 5. Wait for user to authorize and callback to receive code
199
+ const code = await codePromise;
200
+ // 6. Exchange code for tokens
201
+ const tokens = await exchangeCodeForTokens(TOKEN_ENDPOINT, code, clientId, '', // public client, no secret
202
+ redirectUri, codeVerifier, { resource: JMAP_RESOURCE });
203
+ const accessTokenExpiresAt = expiryFromExpiresIn(tokens.expires_in);
204
+ await page.close();
205
+ const credentials = new OAuthCredentials(clientId, '', // public client
206
+ tokens.access_token, tokens.refresh_token, accessTokenExpiresAt);
207
+ return {
208
+ credentials,
209
+ // The JMAP session document is the only thing that names the
210
+ // account; Fastmail's token response carries no identity. A session
211
+ // fetch that fails still leaves usable credentials, so fall back to
212
+ // the placeholder rather than failing the whole login.
213
+ account: (await this.service.getAccount(credentials)) ?? DEFAULT_ACCOUNT,
214
+ };
215
+ }
216
+ catch (error) {
217
+ if (error instanceof Error && isBrowserClosedError(error)) {
218
+ throw new LoginCancelledError();
219
+ }
220
+ throw error;
221
+ }
222
+ finally {
223
+ page.off('close', closeHandler);
224
+ context.off('close', closeHandler);
225
+ }
226
+ });
227
+ }
228
+ }
229
+ export class Fastmail extends Service {
230
+ name = 'fastmail';
231
+ displayName = 'Fastmail';
232
+ /**
233
+ * Four host shapes, which is why these are patterns rather than plain
234
+ * prefixes. Session discovery starts at `api.fastmail.com`, but the `apiUrl`
235
+ * and `downloadUrl` it returns point at the shard the account is homed on
236
+ * (`phl.api.fastmail.com`, `phl-www.fastmailusercontent.com`, …). Which
237
+ * shard that is only becomes known after discovery, so the service has to
238
+ * cover them all up front.
239
+ *
240
+ * The blob pattern is anchored on the `www` label rather than accepting any
241
+ * subdomain: the session document only ever names `www.fastmailusercontent.com`
242
+ * or `<shard>-www.…`, and this is the domain Fastmail uses to serve user
243
+ * content, so matching it loosely would offer the access token to hosts the
244
+ * credential has no business reaching.
245
+ *
246
+ * Deliberately NOT covering carddav.fastmail.com / caldav.fastmail.com. Those
247
+ * advertise `WWW-Authenticate: Basic realm=..., Bearer`, so adding them looks
248
+ * right, but Fastmail's OAuth access tokens are refused there (401 on every
249
+ * path tried, including the principal and per-user collections) — the DAV
250
+ * endpoints want an app password over Basic auth, which is a different
251
+ * credential type than this service issues. Contacts and calendars are
252
+ * reachable over JMAP on the hosts below instead.
253
+ */
254
+ baseApiUrls = [
255
+ /^https:\/\/([a-z0-9-]+\.)?api\.fastmail\.com\//,
256
+ /^https:\/\/([a-z0-9-]+-)?www\.fastmailusercontent\.com\//,
257
+ ];
258
+ loginUrl = AUTHORIZATION_ENDPOINT;
259
+ info = 'https://www.fastmail.com/dev/ and https://jmap.io/spec.html. ' +
260
+ 'Start at https://api.fastmail.com/jmap/session: that session document names the apiUrl, ' +
261
+ 'downloadUrl and account ids for everything else, and its `accounts` entries carry ' +
262
+ '`isReadOnly` and the `accountCapabilities` this credential can reach.';
263
+ credentialCheckCurlArguments = [SESSION_ENDPOINT];
264
+ setCredentialsExample(serviceName) {
265
+ return `latchkey auth set ${serviceName} -H "Authorization: Bearer <token>"`;
266
+ }
267
+ /**
268
+ * Fastmail accepts an OAuth client id prepared in advance via
269
+ * `latchkey auth prepare`, stored as token-less OAuth credentials until
270
+ * login. The login flow reuses this client id instead of registering a new
271
+ * client dynamically.
272
+ */
273
+ prepareFromJson(parsedJson) {
274
+ return buildPreparedCredentials(this.name, FastmailPrepareInputSchema, parsedJson, ({ clientId }) => new OAuthCredentials(clientId, ''));
275
+ }
276
+ getAccount(apiCredentials) {
277
+ return fetchAccountFromEndpoint(apiCredentials, this.credentialCheckCurlArguments, parseAccountFromSession);
278
+ }
279
+ getSession(appNamePrefix) {
280
+ return new FastmailSession(this, appNamePrefix);
281
+ }
282
+ async refreshCredentials(apiCredentials) {
283
+ if (!(apiCredentials instanceof OAuthCredentials)) {
284
+ return null;
285
+ }
286
+ if (!apiCredentials.refreshToken) {
287
+ return null;
288
+ }
289
+ const tokens = await refreshAccessToken(TOKEN_ENDPOINT, apiCredentials.refreshToken, apiCredentials.clientId, apiCredentials.clientSecret, { resource: JMAP_RESOURCE });
290
+ if (tokens === null) {
291
+ return null;
292
+ }
293
+ const accessTokenExpiresAt = expiryFromExpiresIn(tokens.expires_in);
294
+ return new OAuthCredentials(apiCredentials.clientId, apiCredentials.clientSecret, tokens.access_token, tokens.refresh_token ?? apiCredentials.refreshToken, accessTokenExpiresAt, apiCredentials.refreshTokenExpiresAt);
295
+ }
296
+ }
297
+ export const FASTMAIL = new Fastmail();
298
+ //# sourceMappingURL=fastmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastmail.js","sourceRoot":"","sources":["../../../src/services/fastmail.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../../../src/services/google/gmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAOpE,qBAAa,WAAY,SAAQ,aAAa;IAC5C,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,WAAW,kBAAkB;IACtC,QAAQ,CAAC,WAAW,6CAA8C;IAClE,QAAQ,CAAC,IAAI,SAK8D;IAE3E,SAAS,CAAC,QAAQ,CAAC,MAAM,sBAAU;CACpC;AAED,eAAO,MAAM,YAAY,aAAoB,CAAC"}
1
+ {"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../../../src/services/google/gmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAYpE,qBAAa,WAAY,SAAQ,aAAa;IAC5C,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,WAAW,kBAAkB;IACtC,QAAQ,CAAC,WAAW,6CAA8C;IAClE,QAAQ,CAAC,IAAI,SAK8D;IAE3E,SAAS,CAAC,QAAQ,CAAC,MAAM,sBAAU;CACpC;AAED,eAAO,MAAM,YAAY,aAAoB,CAAC"}
@@ -1,7 +1,12 @@
1
1
  import { GoogleService } from './base.js';
2
2
  const CONFIG = {
3
3
  apis: ['gmail.googleapis.com'],
4
- scopes: ['https://www.googleapis.com/auth/gmail.modify'],
4
+ scopes: [
5
+ // gmail.modify covers reading/labeling messages and reading filters/labels,
6
+ // but creating or deleting filters requires gmail.settings.basic.
7
+ 'https://www.googleapis.com/auth/gmail.modify',
8
+ 'https://www.googleapis.com/auth/gmail.settings.basic',
9
+ ],
5
10
  };
6
11
  export class GoogleGmail extends GoogleService {
7
12
  name = 'google-gmail';
@@ -1 +1 @@
1
- {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../../../src/services/google/gmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,WAAW,CAAC;AAEpE,MAAM,MAAM,GAAwB;IAClC,IAAI,EAAE,CAAC,sBAAsB,CAAC;IAC9B,MAAM,EAAE,CAAC,8CAA8C,CAAC;CACzD,CAAC;AAEF,MAAM,OAAO,WAAY,SAAQ,aAAa;IACnC,IAAI,GAAG,cAAc,CAAC;IACtB,WAAW,GAAG,cAAc,CAAC;IAC7B,WAAW,GAAG,CAAC,+BAA+B,CAAU,CAAC;IACzD,IAAI,GACX,0DAA0D;QAC1D,+FAA+F;QAC/F,qEAAqE;QACrE,+HAA+H;QAC/H,wEAAwE,CAAC;IAExD,MAAM,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../../../src/services/google/gmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,WAAW,CAAC;AAEpE,MAAM,MAAM,GAAwB;IAClC,IAAI,EAAE,CAAC,sBAAsB,CAAC;IAC9B,MAAM,EAAE;QACN,4EAA4E;QAC5E,kEAAkE;QAClE,8CAA8C;QAC9C,sDAAsD;KACvD;CACF,CAAC;AAEF,MAAM,OAAO,WAAY,SAAQ,aAAa;IACnC,IAAI,GAAG,cAAc,CAAC;IACtB,WAAW,GAAG,cAAc,CAAC;IAC7B,WAAW,GAAG,CAAC,+BAA+B,CAAU,CAAC;IACzD,IAAI,GACX,0DAA0D;QAC1D,+FAA+F;QAC/F,qEAAqE;QACrE,+HAA+H;QAC/H,wEAAwE,CAAC;IAExD,MAAM,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC"}
@@ -23,6 +23,8 @@ export { GooglePeople, GOOGLE_PEOPLE } from './google/people.js';
23
23
  export { Notion, NOTION } from './notion.js';
24
24
  export { NotionMcp, NOTION_MCP } from './notion-mcp.js';
25
25
  export { Mailchimp, MAILCHIMP } from './mailchimp.js';
26
+ export { Fastmail, FASTMAIL } from './fastmail.js';
27
+ export { FastmailDav, FASTMAIL_DAV } from './fastmail-dav.js';
26
28
  export { Gitlab, GITLAB } from './gitlab.js';
27
29
  export { Zoom, ZOOM } from './zoom.js';
28
30
  export { Telegram, TELEGRAM } from './telegram.js';
@@ -41,4 +43,5 @@ export { Todoist, TODOIST } from './todoist.js';
41
43
  export { Ngrok, NGROK } from './ngrok.js';
42
44
  export { Huggingface, HUGGINGFACE } from './huggingface.js';
43
45
  export { Openrouter, OPENROUTER } from './openrouter.js';
46
+ export { Tailscale, TAILSCALE } from './tailscale.js';
44
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,YAAY,EACZ,2BAA2B,EAC3B,KAAK,WAAW,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,kCAAkC,EAClC,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,8 @@ export { GooglePeople, GOOGLE_PEOPLE } from './google/people.js';
23
23
  export { Notion, NOTION } from './notion.js';
24
24
  export { NotionMcp, NOTION_MCP } from './notion-mcp.js';
25
25
  export { Mailchimp, MAILCHIMP } from './mailchimp.js';
26
+ export { Fastmail, FASTMAIL } from './fastmail.js';
27
+ export { FastmailDav, FASTMAIL_DAV } from './fastmail-dav.js';
26
28
  export { Gitlab, GITLAB } from './gitlab.js';
27
29
  export { Zoom, ZOOM } from './zoom.js';
28
30
  export { Telegram, TELEGRAM } from './telegram.js';
@@ -41,4 +43,5 @@ export { Todoist, TODOIST } from './todoist.js';
41
43
  export { Ngrok, NGROK } from './ngrok.js';
42
44
  export { Huggingface, HUGGINGFACE } from './huggingface.js';
43
45
  export { Openrouter, OPENROUTER } from './openrouter.js';
46
+ export { Tailscale, TAILSCALE } from './tailscale.js';
44
47
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,YAAY,EACZ,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,kCAAkC,EAClC,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,GAGrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Tailscale service implementation.
3
+ *
4
+ * The Tailscale admin API (https://api.tailscale.com/api/v2/) authenticates with
5
+ * an API access token (`tskey-api-...`) that an Owner/Admin creates in the
6
+ * admin console's Keys page. The token's value is revealed exactly once at
7
+ * creation time (like Linear, HuggingFace and OpenRouter), so we sign the user
8
+ * into the admin console, generate a fresh access token on their behalf, and
9
+ * read its value from the one-time reveal dialog.
10
+ *
11
+ * A single API access token grants the full set of actions its owning user may
12
+ * perform: tailnet-wide user management (role changes, approval, suspension,
13
+ * deletion), device management, ACL/policy, DNS, and the minting of further
14
+ * keys (including the auth keys the `tailscale` CLI consumes to bring up
15
+ * nodes). It expires after at most 90 days, after which the user re-runs the
16
+ * browser login to mint a new one -- the token is static and is not refreshable.
17
+ */
18
+ import type { Response, BrowserContext } from 'playwright';
19
+ import { z } from 'zod';
20
+ import { ApiCredentialStatus, ApiCredentials } from '../apiCredentials/base.js';
21
+ import { Service, BrowserFollowupServiceSession, FollowupWork } from './core/base.js';
22
+ /**
23
+ * Credentials for the Tailscale API: a static API access token plus the tailnet
24
+ * it belongs to. The tailnet is part of nearly every useful Tailscale API path
25
+ * and the API exposes no tailnet-independent way to validate a token, so the
26
+ * connector captures it at mint time (it is shown in the admin console's
27
+ * navigation) and stores it alongside the token.
28
+ */
29
+ export declare const TailscaleCredentialsSchema: z.ZodObject<{
30
+ objectType: z.ZodLiteral<"tailscale">;
31
+ token: z.ZodString;
32
+ tailnet: z.ZodString;
33
+ }, "strip", z.ZodTypeAny, {
34
+ objectType: "tailscale";
35
+ token: string;
36
+ tailnet: string;
37
+ }, {
38
+ objectType: "tailscale";
39
+ token: string;
40
+ tailnet: string;
41
+ }>;
42
+ export type TailscaleCredentialsData = z.infer<typeof TailscaleCredentialsSchema>;
43
+ export declare class TailscaleCredentials implements ApiCredentials {
44
+ readonly objectType: "tailscale";
45
+ readonly token: string;
46
+ readonly tailnet: string;
47
+ constructor(token: string, tailnet: string);
48
+ injectIntoCurlCall(curlArguments: readonly string[]): Promise<readonly string[]>;
49
+ isExpired(): boolean | undefined;
50
+ toJSON(): TailscaleCredentialsData;
51
+ static fromJSON(data: TailscaleCredentialsData): TailscaleCredentials;
52
+ }
53
+ declare class TailscaleServiceSession extends BrowserFollowupServiceSession {
54
+ protected readonly followupWork = FollowupWork.CreateApiToken;
55
+ private isLoggedIn;
56
+ onResponse(response: Response): void;
57
+ protected isLoginComplete(): boolean;
58
+ protected performBrowserFollowup(context: BrowserContext, _oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
59
+ }
60
+ export declare class Tailscale extends Service {
61
+ readonly name = "tailscale";
62
+ readonly displayName = "Tailscale";
63
+ readonly baseApiUrls: readonly ["https://api.tailscale.com/"];
64
+ readonly loginUrl = "https://login.tailscale.com/admin";
65
+ readonly info: string;
66
+ readonly credentialCheckCurlArguments: readonly [];
67
+ checkApiCredentials(apiCredentials: ApiCredentials): Promise<ApiCredentialStatus>;
68
+ setCredentialsExample(serviceName: string): string;
69
+ getAccount(apiCredentials: ApiCredentials): Promise<string | null>;
70
+ getSession(appNamePrefix: string): TailscaleServiceSession;
71
+ }
72
+ export declare const TAILSCALE: Tailscale;
73
+ export {};
74
+ //# sourceMappingURL=tailscale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailscale.d.ts","sourceRoot":"","sources":["../../../src/services/tailscale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhF,OAAO,EACL,OAAO,EACP,6BAA6B,EAC7B,YAAY,EAIb,MAAM,gBAAgB,CAAC;AA4BxB;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;EAIrC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAElF,qBAAa,oBAAqB,YAAW,cAAc;IACzD,QAAQ,CAAC,UAAU,EAAG,WAAW,CAAU;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAK1C,kBAAkB,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;IAOhF,SAAS,IAAI,OAAO,GAAG,SAAS;IAIhC,MAAM,IAAI,wBAAwB;IAQlC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,wBAAwB,GAAG,oBAAoB;CAGtE;AAED,cAAM,uBAAwB,SAAQ,6BAA6B;IACjE,SAAS,CAAC,QAAQ,CAAC,YAAY,+BAA+B;IAC9D,OAAO,CAAC,UAAU,CAAS;IAE3B,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAqBpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIpB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,eAAe,CAAC,EAAE,cAAc,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CA+DlC;AAED,qBAAa,SAAU,SAAQ,OAAO;IACpC,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,eAAe;IACnC,QAAQ,CAAC,WAAW,0CAAqC;IACzD,QAAQ,CAAC,QAAQ,uCAAuB;IACxC,QAAQ,CAAC,IAAI,SAO4B;IAKzC,QAAQ,CAAC,4BAA4B,cAAe;IAErC,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BhG,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAOzC,UAAU,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOlE,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,uBAAuB;CAGpE;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}