latchkey 3.14.0 → 3.16.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 (156) hide show
  1. package/README.md +10 -0
  2. package/dist/src/apiCredentials/base.d.ts +53 -5
  3. package/dist/src/apiCredentials/base.d.ts.map +1 -1
  4. package/dist/src/apiCredentials/base.js +43 -9
  5. package/dist/src/apiCredentials/base.js.map +1 -1
  6. package/dist/src/apiCredentials/serialization.d.ts +11 -139
  7. package/dist/src/apiCredentials/serialization.d.ts.map +1 -1
  8. package/dist/src/apiCredentials/serialization.js +53 -81
  9. package/dist/src/apiCredentials/serialization.js.map +1 -1
  10. package/dist/src/apiCredentials/store.d.ts +7 -2
  11. package/dist/src/apiCredentials/store.d.ts.map +1 -1
  12. package/dist/src/apiCredentials/store.js +18 -8
  13. package/dist/src/apiCredentials/store.js.map +1 -1
  14. package/dist/src/browserStateImport.d.ts +50 -0
  15. package/dist/src/browserStateImport.d.ts.map +1 -0
  16. package/dist/src/browserStateImport.js +260 -0
  17. package/dist/src/browserStateImport.js.map +1 -0
  18. package/dist/src/cli.js +13 -2
  19. package/dist/src/cli.js.map +1 -1
  20. package/dist/src/cliCommands.d.ts +15 -7
  21. package/dist/src/cliCommands.d.ts.map +1 -1
  22. package/dist/src/cliCommands.js +64 -16
  23. package/dist/src/cliCommands.js.map +1 -1
  24. package/dist/src/config.d.ts +10 -0
  25. package/dist/src/config.d.ts.map +1 -1
  26. package/dist/src/config.js +15 -0
  27. package/dist/src/config.js.map +1 -1
  28. package/dist/src/configDataStore.d.ts +3 -0
  29. package/dist/src/configDataStore.d.ts.map +1 -1
  30. package/dist/src/configDataStore.js +1 -0
  31. package/dist/src/configDataStore.js.map +1 -1
  32. package/dist/src/curlInjection.d.ts +2 -0
  33. package/dist/src/curlInjection.d.ts.map +1 -1
  34. package/dist/src/curlInjection.js +12 -6
  35. package/dist/src/curlInjection.js.map +1 -1
  36. package/dist/src/diagnosticHeaders.d.ts +19 -0
  37. package/dist/src/diagnosticHeaders.d.ts.map +1 -0
  38. package/dist/src/diagnosticHeaders.js +20 -0
  39. package/dist/src/diagnosticHeaders.js.map +1 -0
  40. package/dist/src/gateway/gatewayEndpoint.d.ts.map +1 -1
  41. package/dist/src/gateway/gatewayEndpoint.js +1 -0
  42. package/dist/src/gateway/gatewayEndpoint.js.map +1 -1
  43. package/dist/src/gateway/server.js +1 -1
  44. package/dist/src/gateway/server.js.map +1 -1
  45. package/dist/src/index.d.ts +3 -3
  46. package/dist/src/index.d.ts.map +1 -1
  47. package/dist/src/index.js +2 -2
  48. package/dist/src/index.js.map +1 -1
  49. package/dist/src/migrations.d.ts.map +1 -1
  50. package/dist/src/migrations.js +8 -8
  51. package/dist/src/migrations.js.map +1 -1
  52. package/dist/src/oauthUtils.d.ts +17 -0
  53. package/dist/src/oauthUtils.d.ts.map +1 -1
  54. package/dist/src/oauthUtils.js +22 -1
  55. package/dist/src/oauthUtils.js.map +1 -1
  56. package/dist/src/pluginSdk.d.ts +118 -0
  57. package/dist/src/pluginSdk.d.ts.map +1 -0
  58. package/dist/src/pluginSdk.js +98 -0
  59. package/dist/src/pluginSdk.js.map +1 -0
  60. package/dist/src/plugins.d.ts +74 -0
  61. package/dist/src/plugins.d.ts.map +1 -0
  62. package/dist/src/plugins.js +221 -0
  63. package/dist/src/plugins.js.map +1 -0
  64. package/dist/src/serviceRegistry.d.ts +2 -2
  65. package/dist/src/serviceRegistry.d.ts.map +1 -1
  66. package/dist/src/serviceRegistry.js +3 -3
  67. package/dist/src/serviceRegistry.js.map +1 -1
  68. package/dist/src/services/aws.d.ts +2 -1
  69. package/dist/src/services/aws.d.ts.map +1 -1
  70. package/dist/src/services/aws.js +4 -2
  71. package/dist/src/services/aws.js.map +1 -1
  72. package/dist/src/services/core/base.d.ts +53 -3
  73. package/dist/src/services/core/base.d.ts.map +1 -1
  74. package/dist/src/services/core/base.js +63 -3
  75. package/dist/src/services/core/base.js.map +1 -1
  76. package/dist/src/services/dropbox.d.ts.map +1 -1
  77. package/dist/src/services/dropbox.js +2 -2
  78. package/dist/src/services/dropbox.js.map +1 -1
  79. package/dist/src/services/fastmail.d.ts +4 -19
  80. package/dist/src/services/fastmail.d.ts.map +1 -1
  81. package/dist/src/services/fastmail.js +17 -22
  82. package/dist/src/services/fastmail.js.map +1 -1
  83. package/dist/src/services/google/base.d.ts +8 -3
  84. package/dist/src/services/google/base.d.ts.map +1 -1
  85. package/dist/src/services/google/base.js +23 -13
  86. package/dist/src/services/google/base.js.map +1 -1
  87. package/dist/src/services/index.d.ts +1 -1
  88. package/dist/src/services/index.d.ts.map +1 -1
  89. package/dist/src/services/index.js +1 -1
  90. package/dist/src/services/index.js.map +1 -1
  91. package/dist/src/services/notion-mcp.d.ts +16 -16
  92. package/dist/src/services/notion-mcp.d.ts.map +1 -1
  93. package/dist/src/services/notion-mcp.js +36 -21
  94. package/dist/src/services/notion-mcp.js.map +1 -1
  95. package/dist/src/services/ramp.d.ts.map +1 -1
  96. package/dist/src/services/ramp.js +2 -2
  97. package/dist/src/services/ramp.js.map +1 -1
  98. package/dist/src/services/slack.d.ts +2 -1
  99. package/dist/src/services/slack.d.ts.map +1 -1
  100. package/dist/src/services/slack.js +4 -2
  101. package/dist/src/services/slack.js.map +1 -1
  102. package/dist/src/services/tailscale.d.ts +2 -1
  103. package/dist/src/services/tailscale.d.ts.map +1 -1
  104. package/dist/src/services/tailscale.js +4 -2
  105. package/dist/src/services/tailscale.js.map +1 -1
  106. package/dist/src/services/telegram.d.ts +2 -1
  107. package/dist/src/services/telegram.d.ts.map +1 -1
  108. package/dist/src/services/telegram.js +4 -2
  109. package/dist/src/services/telegram.js.map +1 -1
  110. package/dist/src/services/zoom.d.ts +7 -5
  111. package/dist/src/services/zoom.d.ts.map +1 -1
  112. package/dist/src/services/zoom.js +11 -8
  113. package/dist/src/services/zoom.js.map +1 -1
  114. package/dist/src/version.d.ts +1 -1
  115. package/dist/src/version.js +1 -1
  116. package/dist/tests/apiCredentialStore.test.js +54 -1
  117. package/dist/tests/apiCredentialStore.test.js.map +1 -1
  118. package/dist/tests/apiCredentials.test.js +73 -12
  119. package/dist/tests/apiCredentials.test.js.map +1 -1
  120. package/dist/tests/browserStateImport.test.d.ts +2 -0
  121. package/dist/tests/browserStateImport.test.d.ts.map +1 -0
  122. package/dist/tests/browserStateImport.test.js +88 -0
  123. package/dist/tests/browserStateImport.test.js.map +1 -0
  124. package/dist/tests/cli.test.js +33 -1
  125. package/dist/tests/cli.test.js.map +1 -1
  126. package/dist/tests/config.test.js +7 -0
  127. package/dist/tests/config.test.js.map +1 -1
  128. package/dist/tests/diagnosticHeaders.test.d.ts +2 -0
  129. package/dist/tests/diagnosticHeaders.test.d.ts.map +1 -0
  130. package/dist/tests/diagnosticHeaders.test.js +22 -0
  131. package/dist/tests/diagnosticHeaders.test.js.map +1 -0
  132. package/dist/tests/followupFailureRecovery.test.d.ts +11 -0
  133. package/dist/tests/followupFailureRecovery.test.d.ts.map +1 -0
  134. package/dist/tests/followupFailureRecovery.test.js +101 -0
  135. package/dist/tests/followupFailureRecovery.test.js.map +1 -0
  136. package/dist/tests/gateway.test.js +25 -4
  137. package/dist/tests/gateway.test.js.map +1 -1
  138. package/dist/tests/gatewayExtensions.test.js +5 -2
  139. package/dist/tests/gatewayExtensions.test.js.map +1 -1
  140. package/dist/tests/latchkeyEndpoint.test.js +8 -6
  141. package/dist/tests/latchkeyEndpoint.test.js.map +1 -1
  142. package/dist/tests/notion-mcp.test.d.ts +2 -0
  143. package/dist/tests/notion-mcp.test.d.ts.map +1 -0
  144. package/dist/tests/notion-mcp.test.js +16 -0
  145. package/dist/tests/notion-mcp.test.js.map +1 -0
  146. package/dist/tests/oauthUtils.test.js +23 -1
  147. package/dist/tests/oauthUtils.test.js.map +1 -1
  148. package/dist/tests/plugins.test.d.ts +2 -0
  149. package/dist/tests/plugins.test.d.ts.map +1 -0
  150. package/dist/tests/plugins.test.js +506 -0
  151. package/dist/tests/plugins.test.js.map +1 -0
  152. package/dist/tests/sharedOperations.test.js +63 -2
  153. package/dist/tests/sharedOperations.test.js.map +1 -1
  154. package/dist/tests/tailscale.test.js +1 -3
  155. package/dist/tests/tailscale.test.js.map +1 -1
  156. package/package.json +15 -1
package/README.md CHANGED
@@ -228,6 +228,15 @@ You can also configure browser login flows for registered services. For details,
228
228
  see `latchkey services register --help`.
229
229
 
230
230
 
231
+ ### Plugins
232
+
233
+ It is also possible to add support for a new service by
234
+ installing a plugin that implements it. A Latchkey plugin is
235
+ a git repository; installation is a matter of running `git
236
+ clone` in `~/.latchkey/plugins/`. For more details, see the
237
+ [plugins docs](./docs/plugins.md).
238
+
239
+
231
240
  ### Indirect credentials
232
241
 
233
242
  Some services can't express their credentials as static curl
@@ -436,6 +445,7 @@ defaults:
436
445
  - `LATCHKEY_GATEWAY_LISTEN_PASSWORD`: optional shared secret used by the server side. When set, `latchkey gateway` rejects (with `401`) any request that does not present the same value in the `X-Latchkey-Gateway-Password` header. The header is stripped before requests are forwarded upstream.
437
446
  - `LATCHKEY_GATEWAY_PERMISSIONS_OVERRIDE`: optional permissions-override JWT (see `latchkey gateway create-jwt`) used by the client side. When set together with `LATCHKEY_GATEWAY`, the CLI sends the value in the `X-Latchkey-Gateway-Permissions-Override` header on every outgoing gateway request, causing the remote gateway to enforce the permissions.json file referenced by the JWT instead of its default one.
438
447
  - `LATCHKEY_APP_NAME_PREFIX`: prefix used for the app, project, and OAuth client names that Latchkey creates on your behalf inside third-party consoles (defaults to `Latchkey`).
448
+ - `LATCHKEY_LATCKEY_DIAGNOSTIC_HEADERS`: if set, Latchkey adds special headers with diagnostic information to the outgoing requests. This currently includes `X-Latchkey-Matched-Service`, indicating the service that Latchkey matched the request to and injected credentials for.
439
449
 
440
450
  All of the above settings, except for `LATCHKEY_DIRECTORY`,
441
451
  `LATCHKEY_ENCRYPTION_KEY`, `LATCHKEY_GATEWAY_PASSWORD`,
@@ -8,12 +8,24 @@ export declare enum ApiCredentialStatus {
8
8
  Invalid = "invalid",
9
9
  Unknown = "unknown"
10
10
  }
11
+ /**
12
+ * The stored form of credentials: plain JSON whose `objectType` names the
13
+ * {@link ApiCredentialsType} that can read it back.
14
+ */
15
+ export interface SerializedApiCredentials {
16
+ readonly objectType: string;
17
+ }
11
18
  /**
12
19
  * Base interface for all API credentials.
13
20
  * Each credential type must specify how to inject itself into a curl call.
14
21
  */
15
22
  export interface ApiCredentials {
16
23
  readonly objectType: string;
24
+ /**
25
+ * The form the credentials are stored in. Left out by credentials that are
26
+ * only ever built on the fly from stored ones and never stored themselves.
27
+ */
28
+ toJSON?(): SerializedApiCredentials;
17
29
  /**
18
30
  * Inject credentials into a curl call by modifying the given arguments array.
19
31
  * Implementations may add headers, change the URL, or transform arguments in any way.
@@ -31,6 +43,17 @@ export interface ApiCredentials {
31
43
  */
32
44
  isExpired(): boolean | undefined;
33
45
  }
46
+ /**
47
+ * How stored credentials of one `objectType` are read back. This is the static
48
+ * side of a credentials class: `fromJSON` validates the stored JSON and builds
49
+ * the credentials from it, throwing on data it does not accept. Every
50
+ * credentials class latchkey ships with is one, and a plugin that defines its
51
+ * own class lists it in its manifest so that its credentials can be stored.
52
+ */
53
+ export interface ApiCredentialsType {
54
+ readonly objectType: string;
55
+ fromJSON(data: unknown): ApiCredentials;
56
+ }
34
57
  /**
35
58
  * Bearer token authentication (Authorization: Bearer <token>).
36
59
  */
@@ -46,13 +69,14 @@ export declare const AuthorizationBearerSchema: z.ZodObject<{
46
69
  }>;
47
70
  export type AuthorizationBearerData = z.infer<typeof AuthorizationBearerSchema>;
48
71
  export declare class AuthorizationBearer implements ApiCredentials {
72
+ static readonly objectType: "authorizationBearer";
49
73
  readonly objectType: "authorizationBearer";
50
74
  readonly token: string;
51
75
  constructor(token: string);
52
76
  injectIntoCurlCall(curlArguments: readonly string[]): Promise<readonly string[]>;
53
77
  isExpired(): boolean | undefined;
54
78
  toJSON(): AuthorizationBearerData;
55
- static fromJSON(data: AuthorizationBearerData): AuthorizationBearer;
79
+ static fromJSON(data: unknown): AuthorizationBearer;
56
80
  }
57
81
  /**
58
82
  * Raw authorization header (Authorization: <token>).
@@ -69,13 +93,14 @@ export declare const AuthorizationBareSchema: z.ZodObject<{
69
93
  }>;
70
94
  export type AuthorizationBareData = z.infer<typeof AuthorizationBareSchema>;
71
95
  export declare class AuthorizationBare implements ApiCredentials {
96
+ static readonly objectType: "authorizationBare";
72
97
  readonly objectType: "authorizationBare";
73
98
  readonly token: string;
74
99
  constructor(token: string);
75
100
  injectIntoCurlCall(curlArguments: readonly string[]): Promise<readonly string[]>;
76
101
  isExpired(): boolean | undefined;
77
102
  toJSON(): AuthorizationBareData;
78
- static fromJSON(data: AuthorizationBareData): AuthorizationBare;
103
+ static fromJSON(data: unknown): AuthorizationBare;
79
104
  }
80
105
  /**
81
106
  * Raw curl arguments stored directly as credentials.
@@ -93,13 +118,14 @@ export declare const RawCurlCredentialsSchema: z.ZodObject<{
93
118
  }>;
94
119
  export type RawCurlCredentialsData = z.infer<typeof RawCurlCredentialsSchema>;
95
120
  export declare class RawCurlCredentials implements ApiCredentials {
121
+ static readonly objectType: "rawCurl";
96
122
  readonly objectType: "rawCurl";
97
123
  readonly curlArguments: readonly string[];
98
124
  constructor(curlArguments: readonly string[]);
99
125
  injectIntoCurlCall(curlArguments: readonly string[]): Promise<readonly string[]>;
100
126
  isExpired(): boolean | undefined;
101
127
  toJSON(): RawCurlCredentialsData;
102
- static fromJSON(data: RawCurlCredentialsData): RawCurlCredentials;
128
+ static fromJSON(data: unknown): RawCurlCredentials;
103
129
  }
104
130
  /**
105
131
  * OAuth 2.0 credentials (access token, refresh token, client ID, and client secret).
@@ -115,6 +141,7 @@ export declare const OAuthCredentialsSchema: z.ZodObject<{
115
141
  clientSecret: z.ZodString;
116
142
  accessTokenExpiresAt: z.ZodOptional<z.ZodString>;
117
143
  refreshTokenExpiresAt: z.ZodOptional<z.ZodString>;
144
+ redirectUri: z.ZodOptional<z.ZodString>;
118
145
  }, "strip", z.ZodTypeAny, {
119
146
  objectType: "oauth";
120
147
  clientId: string;
@@ -123,6 +150,7 @@ export declare const OAuthCredentialsSchema: z.ZodObject<{
123
150
  refreshToken?: string | undefined;
124
151
  accessTokenExpiresAt?: string | undefined;
125
152
  refreshTokenExpiresAt?: string | undefined;
153
+ redirectUri?: string | undefined;
126
154
  }, {
127
155
  objectType: "oauth";
128
156
  clientId: string;
@@ -131,9 +159,11 @@ export declare const OAuthCredentialsSchema: z.ZodObject<{
131
159
  refreshToken?: string | undefined;
132
160
  accessTokenExpiresAt?: string | undefined;
133
161
  refreshTokenExpiresAt?: string | undefined;
162
+ redirectUri?: string | undefined;
134
163
  }>;
135
164
  export type OAuthCredentialsData = z.infer<typeof OAuthCredentialsSchema>;
136
165
  export declare class OAuthCredentials implements ApiCredentials {
166
+ static readonly objectType: "oauth";
137
167
  readonly objectType: "oauth";
138
168
  readonly accessToken?: string;
139
169
  readonly refreshToken?: string;
@@ -141,11 +171,29 @@ export declare class OAuthCredentials implements ApiCredentials {
141
171
  readonly clientSecret: string;
142
172
  readonly accessTokenExpiresAt?: string;
143
173
  readonly refreshTokenExpiresAt?: string;
144
- constructor(clientId: string, clientSecret: string, accessToken?: string, refreshToken?: string, accessTokenExpiresAt?: string, refreshTokenExpiresAt?: string);
174
+ /**
175
+ * Where the authorization server sends the user back to, when the OAuth
176
+ * client only permits a pre-registered redirect URI. Left unset in the usual
177
+ * case, where login stands up its own loopback server and uses
178
+ * `http://localhost:<port>/oauth2callback`.
179
+ *
180
+ * An application that embeds latchkey sets this via `latchkey auth prepare`,
181
+ * pointing at a page of its own. That page has to forward the query string
182
+ * the authorization server appended (`code` and friends) to latchkey's
183
+ * loopback callback; the port is not fixed, so services that support an
184
+ * override pass it in the `state` parameter for the page to read back.
185
+ */
186
+ readonly redirectUri?: string;
187
+ constructor(clientId: string, clientSecret: string, accessToken?: string, refreshToken?: string, accessTokenExpiresAt?: string, refreshTokenExpiresAt?: string, redirectUri?: string);
188
+ /**
189
+ * The token-less form a preparation is stored in: the OAuth client the next
190
+ * login should use, optionally with the redirect URI it is registered with.
191
+ */
192
+ static prepared(clientId: string, clientSecret: string, redirectUri?: string): OAuthCredentials;
145
193
  injectIntoCurlCall(curlArguments: readonly string[]): Promise<readonly string[]>;
146
194
  isExpired(): boolean | undefined;
147
195
  toJSON(): OAuthCredentialsData;
148
- static fromJSON(data: OAuthCredentialsData): OAuthCredentials;
196
+ static fromJSON(data: unknown): OAuthCredentials;
149
197
  }
150
198
  export declare class ApiCredentialsUsageError extends Error {
151
199
  constructor(message: string);
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/apiCredentials/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/apiCredentials/base.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,8 @@ export const AuthorizationBearerSchema = z.object({
17
17
  token: z.string(),
18
18
  });
19
19
  export class AuthorizationBearer {
20
- objectType = 'authorizationBearer';
20
+ static objectType = 'authorizationBearer';
21
+ objectType = AuthorizationBearer.objectType;
21
22
  token;
22
23
  constructor(token) {
23
24
  this.token = token;
@@ -35,7 +36,8 @@ export class AuthorizationBearer {
35
36
  };
36
37
  }
37
38
  static fromJSON(data) {
38
- return new AuthorizationBearer(data.token);
39
+ const parsed = AuthorizationBearerSchema.parse(data);
40
+ return new AuthorizationBearer(parsed.token);
39
41
  }
40
42
  }
41
43
  /**
@@ -46,7 +48,8 @@ export const AuthorizationBareSchema = z.object({
46
48
  token: z.string(),
47
49
  });
48
50
  export class AuthorizationBare {
49
- objectType = 'authorizationBare';
51
+ static objectType = 'authorizationBare';
52
+ objectType = AuthorizationBare.objectType;
50
53
  token;
51
54
  constructor(token) {
52
55
  this.token = token;
@@ -64,7 +67,8 @@ export class AuthorizationBare {
64
67
  };
65
68
  }
66
69
  static fromJSON(data) {
67
- return new AuthorizationBare(data.token);
70
+ const parsed = AuthorizationBareSchema.parse(data);
71
+ return new AuthorizationBare(parsed.token);
68
72
  }
69
73
  }
70
74
  /**
@@ -76,7 +80,8 @@ export const RawCurlCredentialsSchema = z.object({
76
80
  curlArguments: z.array(z.string()),
77
81
  });
78
82
  export class RawCurlCredentials {
79
- objectType = 'rawCurl';
83
+ static objectType = 'rawCurl';
84
+ objectType = RawCurlCredentials.objectType;
80
85
  curlArguments;
81
86
  constructor(curlArguments) {
82
87
  this.curlArguments = curlArguments;
@@ -94,7 +99,8 @@ export class RawCurlCredentials {
94
99
  };
95
100
  }
96
101
  static fromJSON(data) {
97
- return new RawCurlCredentials(data.curlArguments);
102
+ const parsed = RawCurlCredentialsSchema.parse(data);
103
+ return new RawCurlCredentials(parsed.curlArguments);
98
104
  }
99
105
  }
100
106
  /**
@@ -111,22 +117,48 @@ export const OAuthCredentialsSchema = z.object({
111
117
  clientSecret: z.string(),
112
118
  accessTokenExpiresAt: z.string().optional(),
113
119
  refreshTokenExpiresAt: z.string().optional(),
120
+ redirectUri: z.string().optional(),
114
121
  });
115
122
  export class OAuthCredentials {
116
- objectType = 'oauth';
123
+ static objectType = 'oauth';
124
+ objectType = OAuthCredentials.objectType;
117
125
  accessToken;
118
126
  refreshToken;
119
127
  clientId;
120
128
  clientSecret;
121
129
  accessTokenExpiresAt;
122
130
  refreshTokenExpiresAt;
123
- constructor(clientId, clientSecret, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt) {
131
+ /**
132
+ * Where the authorization server sends the user back to, when the OAuth
133
+ * client only permits a pre-registered redirect URI. Left unset in the usual
134
+ * case, where login stands up its own loopback server and uses
135
+ * `http://localhost:<port>/oauth2callback`.
136
+ *
137
+ * An application that embeds latchkey sets this via `latchkey auth prepare`,
138
+ * pointing at a page of its own. That page has to forward the query string
139
+ * the authorization server appended (`code` and friends) to latchkey's
140
+ * loopback callback; the port is not fixed, so services that support an
141
+ * override pass it in the `state` parameter for the page to read back.
142
+ */
143
+ redirectUri;
144
+ // `redirectUri` trails the token fields, out of its natural place next to
145
+ // the client id and secret, so that existing positional callers — including
146
+ // plugins built against an earlier version — keep working.
147
+ constructor(clientId, clientSecret, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt, redirectUri) {
124
148
  this.clientId = clientId;
125
149
  this.clientSecret = clientSecret;
126
150
  this.accessToken = accessToken;
127
151
  this.refreshToken = refreshToken;
128
152
  this.accessTokenExpiresAt = accessTokenExpiresAt;
129
153
  this.refreshTokenExpiresAt = refreshTokenExpiresAt;
154
+ this.redirectUri = redirectUri;
155
+ }
156
+ /**
157
+ * The token-less form a preparation is stored in: the OAuth client the next
158
+ * login should use, optionally with the redirect URI it is registered with.
159
+ */
160
+ static prepared(clientId, clientSecret, redirectUri) {
161
+ return new OAuthCredentials(clientId, clientSecret, undefined, undefined, undefined, undefined, redirectUri);
130
162
  }
131
163
  injectIntoCurlCall(curlArguments) {
132
164
  if (this.accessToken === undefined) {
@@ -150,11 +182,13 @@ export class OAuthCredentials {
150
182
  refreshToken: this.refreshToken,
151
183
  accessTokenExpiresAt: this.accessTokenExpiresAt,
152
184
  refreshTokenExpiresAt: this.refreshTokenExpiresAt,
185
+ redirectUri: this.redirectUri,
153
186
  };
154
187
  return result;
155
188
  }
156
189
  static fromJSON(data) {
157
- return new OAuthCredentials(data.clientId, data.clientSecret, data.accessToken, data.refreshToken, data.accessTokenExpiresAt, data.refreshTokenExpiresAt);
190
+ const parsed = OAuthCredentialsSchema.parse(data);
191
+ return new OAuthCredentials(parsed.clientId, parsed.clientSecret, parsed.accessToken, parsed.refreshToken, parsed.accessTokenExpiresAt, parsed.refreshTokenExpiresAt, parsed.redirectUri);
158
192
  }
159
193
  }
160
194
  export class ApiCredentialsUsageError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/apiCredentials/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/apiCredentials/base.ts"],"names":[],"mappings":"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"}
@@ -4,148 +4,20 @@
4
4
  * This module is separate from base.ts to avoid circular dependencies:
5
5
  * service files import base types from base.ts, and this module imports
6
6
  * from both base.ts and service files.
7
+ *
8
+ * Which credentials can be read back is decided by a list of
9
+ * {@link ApiCredentialsType}s. {@link BUILTIN_API_CREDENTIALS_TYPES} covers
10
+ * everything Latchkey ships with and is the default; the CLI passes the
11
+ * combined built-in and plugin list instead.
7
12
  */
8
- import { z } from 'zod';
9
- import { type ApiCredentials } from './base.js';
10
- /**
11
- * Union schema for all credential types.
12
- */
13
- export declare const ApiCredentialsSchema: z.ZodDiscriminatedUnion<"objectType", [z.ZodObject<{
14
- objectType: z.ZodLiteral<"authorizationBearer">;
15
- token: z.ZodString;
16
- }, "strip", z.ZodTypeAny, {
17
- objectType: "authorizationBearer";
18
- token: string;
19
- }, {
20
- objectType: "authorizationBearer";
21
- token: string;
22
- }>, z.ZodObject<{
23
- objectType: z.ZodLiteral<"authorizationBare">;
24
- token: z.ZodString;
25
- }, "strip", z.ZodTypeAny, {
26
- objectType: "authorizationBare";
27
- token: string;
28
- }, {
29
- objectType: "authorizationBare";
30
- token: string;
31
- }>, z.ZodObject<{
32
- objectType: z.ZodLiteral<"slack">;
33
- token: z.ZodString;
34
- dCookie: z.ZodString;
35
- }, "strip", z.ZodTypeAny, {
36
- objectType: "slack";
37
- token: string;
38
- dCookie: string;
39
- }, {
40
- objectType: "slack";
41
- token: string;
42
- dCookie: string;
43
- }>, z.ZodObject<{
44
- objectType: z.ZodLiteral<"oauth">;
45
- accessToken: z.ZodOptional<z.ZodString>;
46
- refreshToken: z.ZodOptional<z.ZodString>;
47
- clientId: z.ZodString;
48
- clientSecret: z.ZodString;
49
- accessTokenExpiresAt: z.ZodOptional<z.ZodString>;
50
- refreshTokenExpiresAt: z.ZodOptional<z.ZodString>;
51
- }, "strip", z.ZodTypeAny, {
52
- objectType: "oauth";
53
- clientId: string;
54
- clientSecret: string;
55
- accessToken?: string | undefined;
56
- refreshToken?: string | undefined;
57
- accessTokenExpiresAt?: string | undefined;
58
- refreshTokenExpiresAt?: string | undefined;
59
- }, {
60
- objectType: "oauth";
61
- clientId: string;
62
- clientSecret: string;
63
- accessToken?: string | undefined;
64
- refreshToken?: string | undefined;
65
- accessTokenExpiresAt?: string | undefined;
66
- refreshTokenExpiresAt?: string | undefined;
67
- }>, z.ZodObject<{
68
- objectType: z.ZodLiteral<"rawCurl">;
69
- curlArguments: z.ZodArray<z.ZodString, "many">;
70
- }, "strip", z.ZodTypeAny, {
71
- objectType: "rawCurl";
72
- curlArguments: string[];
73
- }, {
74
- objectType: "rawCurl";
75
- curlArguments: string[];
76
- }>, z.ZodObject<{
77
- objectType: z.ZodLiteral<"telegramBot">;
78
- token: z.ZodString;
79
- }, "strip", z.ZodTypeAny, {
80
- objectType: "telegramBot";
81
- token: string;
82
- }, {
83
- objectType: "telegramBot";
84
- token: string;
85
- }>, z.ZodObject<{
86
- objectType: z.ZodLiteral<"aws">;
87
- accessKeyId: z.ZodString;
88
- secretAccessKey: z.ZodString;
89
- }, "strip", z.ZodTypeAny, {
90
- objectType: "aws";
91
- accessKeyId: string;
92
- secretAccessKey: string;
93
- }, {
94
- objectType: "aws";
95
- accessKeyId: string;
96
- secretAccessKey: string;
97
- }>, z.ZodObject<{
98
- objectType: z.ZodLiteral<"googleApiKey">;
99
- apiKey: z.ZodString;
100
- }, "strip", z.ZodTypeAny, {
101
- objectType: "googleApiKey";
102
- apiKey: string;
103
- }, {
104
- objectType: "googleApiKey";
105
- apiKey: string;
106
- }>, z.ZodObject<{
107
- objectType: z.ZodLiteral<"zoomServerToServer">;
108
- accountId: z.ZodString;
109
- clientId: z.ZodString;
110
- clientSecret: z.ZodString;
111
- accessToken: z.ZodOptional<z.ZodString>;
112
- accessTokenExpiresAt: z.ZodOptional<z.ZodString>;
113
- }, "strip", z.ZodTypeAny, {
114
- objectType: "zoomServerToServer";
115
- clientId: string;
116
- clientSecret: string;
117
- accountId: string;
118
- accessToken?: string | undefined;
119
- accessTokenExpiresAt?: string | undefined;
120
- }, {
121
- objectType: "zoomServerToServer";
122
- clientId: string;
123
- clientSecret: string;
124
- accountId: string;
125
- accessToken?: string | undefined;
126
- accessTokenExpiresAt?: string | undefined;
127
- }>, z.ZodObject<{
128
- objectType: z.ZodLiteral<"tailscale">;
129
- token: z.ZodString;
130
- tailnet: z.ZodString;
131
- }, "strip", z.ZodTypeAny, {
132
- objectType: "tailscale";
133
- token: string;
134
- tailnet: string;
135
- }, {
136
- objectType: "tailscale";
137
- token: string;
138
- tailnet: string;
139
- }>]>;
140
- export type ApiCredentialsData = z.infer<typeof ApiCredentialsSchema>;
141
- /**
142
- * Deserialize credentials from JSON data.
143
- */
144
- export declare function deserializeCredentials(data: ApiCredentialsData): ApiCredentials;
13
+ import { type ApiCredentials, type ApiCredentialsType, type SerializedApiCredentials } from './base.js';
14
+ export declare const BUILTIN_API_CREDENTIALS_TYPES: readonly ApiCredentialsType[];
15
+ export declare function deserializeCredentials(data: unknown, apiCredentialsTypes?: readonly ApiCredentialsType[]): ApiCredentials;
145
16
  /**
146
- * Serialize credentials to JSON data.
17
+ * Refuses credentials that could not be read back afterwards, so that the
18
+ * mistake surfaces when they are stored rather than when they are needed.
147
19
  */
148
- export declare function serializeCredentials(credentials: ApiCredentials): ApiCredentialsData;
20
+ export declare function serializeCredentials(credentials: ApiCredentials, apiCredentialsTypes?: readonly ApiCredentialsType[]): SerializedApiCredentials;
149
21
  export declare class ApiCredentialsSerializationError extends Error {
150
22
  constructor(message: string);
151
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/apiCredentials/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,KAAK,cAAc,EASpB,MAAM,WAAW,CAAC;AAWnB;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAW/B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtE;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CA6B/E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,cAAc,GAAG,kBAAkB,CAgCpF;AAED,qBAAa,gCAAiC,SAAQ,KAAK;gBAC7C,OAAO,EAAE,MAAM;CAI5B"}
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/apiCredentials/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAK9B,MAAM,WAAW,CAAC;AAQnB,eAAO,MAAM,6BAA6B,EAAE,SAAS,kBAAkB,EAWtE,CAAC;AAWF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,mBAAmB,GAAE,SAAS,kBAAkB,EAAkC,GACjF,cAAc,CAqBhB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,cAAc,EAC3B,mBAAmB,GAAE,SAAS,kBAAkB,EAAkC,GACjF,wBAAwB,CAa1B;AAED,qBAAa,gCAAiC,SAAQ,KAAK;gBAC7C,OAAO,EAAE,MAAM;CAI5B"}
@@ -4,96 +4,68 @@
4
4
  * This module is separate from base.ts to avoid circular dependencies:
5
5
  * service files import base types from base.ts, and this module imports
6
6
  * from both base.ts and service files.
7
+ *
8
+ * Which credentials can be read back is decided by a list of
9
+ * {@link ApiCredentialsType}s. {@link BUILTIN_API_CREDENTIALS_TYPES} covers
10
+ * everything Latchkey ships with and is the default; the CLI passes the
11
+ * combined built-in and plugin list instead.
7
12
  */
8
13
  import { z } from 'zod';
9
- import { AuthorizationBare, AuthorizationBareSchema, AuthorizationBearer, AuthorizationBearerSchema, OAuthCredentials, OAuthCredentialsSchema, RawCurlCredentials, RawCurlCredentialsSchema, } from './base.js';
10
- import { AwsCredentials, AwsCredentialsSchema } from '../services/aws.js';
11
- import { GoogleApiKeyCredentials, GoogleApiKeyCredentialsSchema } from '../services/google/base.js';
12
- import { SlackApiCredentials, SlackApiCredentialsSchema } from '../services/slack.js';
13
- import { TelegramBotCredentials, TelegramBotCredentialsSchema } from '../services/telegram.js';
14
- import { ZoomServerToServerCredentials, ZoomServerToServerCredentialsSchema, } from '../services/zoom.js';
15
- import { TailscaleCredentials, TailscaleCredentialsSchema } from '../services/tailscale.js';
16
- /**
17
- * Union schema for all credential types.
18
- */
19
- export const ApiCredentialsSchema = z.discriminatedUnion('objectType', [
20
- AuthorizationBearerSchema,
21
- AuthorizationBareSchema,
22
- SlackApiCredentialsSchema,
23
- OAuthCredentialsSchema,
24
- RawCurlCredentialsSchema,
25
- TelegramBotCredentialsSchema,
26
- AwsCredentialsSchema,
27
- GoogleApiKeyCredentialsSchema,
28
- ZoomServerToServerCredentialsSchema,
29
- TailscaleCredentialsSchema,
30
- ]);
31
- /**
32
- * Deserialize credentials from JSON data.
33
- */
34
- export function deserializeCredentials(data) {
35
- switch (data.objectType) {
36
- case 'authorizationBearer':
37
- return AuthorizationBearer.fromJSON(data);
38
- case 'authorizationBare':
39
- return AuthorizationBare.fromJSON(data);
40
- case 'slack':
41
- return SlackApiCredentials.fromJSON(data);
42
- case 'oauth':
43
- return OAuthCredentials.fromJSON(data);
44
- case 'rawCurl':
45
- return RawCurlCredentials.fromJSON(data);
46
- case 'telegramBot':
47
- return TelegramBotCredentials.fromJSON(data);
48
- case 'aws':
49
- return AwsCredentials.fromJSON(data);
50
- case 'googleApiKey':
51
- return GoogleApiKeyCredentials.fromJSON(data);
52
- case 'zoomServerToServer':
53
- return ZoomServerToServerCredentials.fromJSON(data);
54
- case 'tailscale':
55
- return TailscaleCredentials.fromJSON(data);
56
- default: {
57
- const exhaustiveCheck = data;
58
- throw new ApiCredentialsSerializationError(`Unknown credential type: ${exhaustiveCheck.objectType}`);
59
- }
60
- }
14
+ import { AuthorizationBare, AuthorizationBearer, OAuthCredentials, RawCurlCredentials, } from './base.js';
15
+ import { AwsCredentials } from '../services/aws.js';
16
+ import { GoogleApiKeyCredentials } from '../services/google/base.js';
17
+ import { SlackApiCredentials } from '../services/slack.js';
18
+ import { TelegramBotCredentials } from '../services/telegram.js';
19
+ import { ZoomServerToServerCredentials } from '../services/zoom.js';
20
+ import { TailscaleCredentials } from '../services/tailscale.js';
21
+ export const BUILTIN_API_CREDENTIALS_TYPES = [
22
+ AuthorizationBearer,
23
+ AuthorizationBare,
24
+ SlackApiCredentials,
25
+ OAuthCredentials,
26
+ RawCurlCredentials,
27
+ TelegramBotCredentials,
28
+ AwsCredentials,
29
+ GoogleApiKeyCredentials,
30
+ ZoomServerToServerCredentials,
31
+ TailscaleCredentials,
32
+ ];
33
+ const OBJECT_TYPE_SCHEMA = z.object({ objectType: z.string() });
34
+ function findApiCredentialsType(objectType, apiCredentialsTypes) {
35
+ return apiCredentialsTypes.find((type) => type.objectType === objectType);
61
36
  }
62
- /**
63
- * Serialize credentials to JSON data.
64
- */
65
- export function serializeCredentials(credentials) {
66
- if (credentials instanceof AuthorizationBearer) {
67
- return credentials.toJSON();
37
+ export function deserializeCredentials(data, apiCredentialsTypes = BUILTIN_API_CREDENTIALS_TYPES) {
38
+ const header = OBJECT_TYPE_SCHEMA.safeParse(data);
39
+ if (!header.success) {
40
+ throw new ApiCredentialsSerializationError('Credential data does not name an objectType.');
68
41
  }
69
- if (credentials instanceof AuthorizationBare) {
70
- return credentials.toJSON();
42
+ const objectType = header.data.objectType;
43
+ const type = findApiCredentialsType(objectType, apiCredentialsTypes);
44
+ if (type === undefined) {
45
+ throw new ApiCredentialsSerializationError(`Unknown credential type '${objectType}'. Credentials of a type defined by a plugin ` +
46
+ 'can only be used while that plugin is installed.');
71
47
  }
72
- if (credentials instanceof SlackApiCredentials) {
73
- return credentials.toJSON();
48
+ try {
49
+ return type.fromJSON(data);
74
50
  }
75
- if (credentials instanceof OAuthCredentials) {
76
- return credentials.toJSON();
51
+ catch (error) {
52
+ const message = error instanceof Error ? error.message : String(error);
53
+ throw new ApiCredentialsSerializationError(`Invalid '${objectType}' credential data: ${message}`);
77
54
  }
78
- if (credentials instanceof RawCurlCredentials) {
79
- return credentials.toJSON();
80
- }
81
- if (credentials instanceof TelegramBotCredentials) {
82
- return credentials.toJSON();
83
- }
84
- if (credentials instanceof AwsCredentials) {
85
- return credentials.toJSON();
86
- }
87
- if (credentials instanceof GoogleApiKeyCredentials) {
88
- return credentials.toJSON();
89
- }
90
- if (credentials instanceof ZoomServerToServerCredentials) {
91
- return credentials.toJSON();
55
+ }
56
+ /**
57
+ * Refuses credentials that could not be read back afterwards, so that the
58
+ * mistake surfaces when they are stored rather than when they are needed.
59
+ */
60
+ export function serializeCredentials(credentials, apiCredentialsTypes = BUILTIN_API_CREDENTIALS_TYPES) {
61
+ if (credentials.toJSON === undefined) {
62
+ throw new ApiCredentialsSerializationError(`Credentials of type '${credentials.objectType}' are never stored.`);
92
63
  }
93
- if (credentials instanceof TailscaleCredentials) {
94
- return credentials.toJSON();
64
+ if (findApiCredentialsType(credentials.objectType, apiCredentialsTypes) === undefined) {
65
+ throw new ApiCredentialsSerializationError(`Unknown credential type '${credentials.objectType}'. A plugin defining its own ` +
66
+ "credentials class has to list its type in 'apiCredentialsTypes'.");
95
67
  }
96
- throw new ApiCredentialsSerializationError(`Unknown credential type: ${credentials.objectType}`);
68
+ return credentials.toJSON();
97
69
  }
98
70
  export class ApiCredentialsSerializationError extends Error {
99
71
  constructor(message) {