latchkey 3.2.2 → 3.3.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 (48) hide show
  1. package/README.md +2 -1
  2. package/dist/src/cliCommands.d.ts.map +1 -1
  3. package/dist/src/cliCommands.js +91 -7
  4. package/dist/src/cliCommands.js.map +1 -1
  5. package/dist/src/configDataStore.d.ts +18 -0
  6. package/dist/src/configDataStore.d.ts.map +1 -1
  7. package/dist/src/configDataStore.js +10 -0
  8. package/dist/src/configDataStore.js.map +1 -1
  9. package/dist/src/serviceRegistry.d.ts.map +1 -1
  10. package/dist/src/serviceRegistry.js +25 -2
  11. package/dist/src/serviceRegistry.js.map +1 -1
  12. package/dist/src/services/core/base.d.ts +25 -3
  13. package/dist/src/services/core/base.d.ts.map +1 -1
  14. package/dist/src/services/core/base.js +32 -10
  15. package/dist/src/services/core/base.js.map +1 -1
  16. package/dist/src/services/core/loginFlows/base.d.ts +75 -0
  17. package/dist/src/services/core/loginFlows/base.d.ts.map +1 -0
  18. package/dist/src/services/core/loginFlows/base.js +47 -0
  19. package/dist/src/services/core/loginFlows/base.js.map +1 -0
  20. package/dist/src/services/core/loginFlows/cookieCapture.d.ts +55 -0
  21. package/dist/src/services/core/loginFlows/cookieCapture.d.ts.map +1 -0
  22. package/dist/src/services/core/loginFlows/cookieCapture.js +244 -0
  23. package/dist/src/services/core/loginFlows/cookieCapture.js.map +1 -0
  24. package/dist/src/services/core/loginFlows/registry.d.ts +30 -0
  25. package/dist/src/services/core/loginFlows/registry.d.ts.map +1 -0
  26. package/dist/src/services/core/loginFlows/registry.js +56 -0
  27. package/dist/src/services/core/loginFlows/registry.js.map +1 -0
  28. package/dist/src/services/core/registered.d.ts +38 -2
  29. package/dist/src/services/core/registered.d.ts.map +1 -1
  30. package/dist/src/services/core/registered.js +37 -2
  31. package/dist/src/services/core/registered.js.map +1 -1
  32. package/dist/src/services/index.d.ts +3 -0
  33. package/dist/src/services/index.d.ts.map +1 -1
  34. package/dist/src/services/index.js +3 -0
  35. package/dist/src/services/index.js.map +1 -1
  36. package/dist/src/version.d.ts +1 -1
  37. package/dist/src/version.js +1 -1
  38. package/dist/tests/cli.test.js +178 -2
  39. package/dist/tests/cli.test.js.map +1 -1
  40. package/dist/tests/cookieCapture.test.d.ts +10 -0
  41. package/dist/tests/cookieCapture.test.d.ts.map +1 -0
  42. package/dist/tests/cookieCapture.test.js +221 -0
  43. package/dist/tests/cookieCapture.test.js.map +1 -0
  44. package/dist/tests/serviceRegistry.test.js +29 -8
  45. package/dist/tests/serviceRegistry.test.js.map +1 -1
  46. package/dist/tests/servicesAgainstRecordings.test.js +5 -9
  47. package/dist/tests/servicesAgainstRecordings.test.js.map +1 -1
  48. package/package.json +1 -1
@@ -55,16 +55,22 @@ export class PrepareInputInvalidError extends Error {
55
55
  export function buildPreparedCredentials(serviceName, schema, parsedJson, build) {
56
56
  const result = schema.safeParse(parsedJson);
57
57
  if (!result.success) {
58
- const detail = result.error.issues
59
- .map((issue) => {
60
- const path = issue.path.join('.');
61
- return path ? `${path}: ${issue.message}` : issue.message;
62
- })
63
- .join('; ');
64
- throw new PrepareInputInvalidError(serviceName, detail);
58
+ throw new PrepareInputInvalidError(serviceName, describeSchemaIssues(result.error));
65
59
  }
66
60
  return build(result.data);
67
61
  }
62
+ /**
63
+ * Render the failing fields of a schema mismatch as a single line, so every
64
+ * command that validates JSON input reports problems the same way.
65
+ */
66
+ export function describeSchemaIssues(error) {
67
+ return error.issues
68
+ .map((issue) => {
69
+ const path = issue.path.join('.');
70
+ return path ? `${path}: ${issue.message}` : issue.message;
71
+ })
72
+ .join('; ');
73
+ }
68
74
  export function isBrowserClosedError(error) {
69
75
  const message = error.message.toLowerCase();
70
76
  return (message.includes('target closed') ||
@@ -191,7 +197,7 @@ export class ServiceSession {
191
197
  return withTempBrowserContext(encryptedStorage, launchOptions, async ({ browser, context }) => {
192
198
  const page = await context.newPage();
193
199
  context.on('response', (response) => {
194
- this.onResponse(response);
200
+ void this.onResponse(response);
195
201
  });
196
202
  try {
197
203
  await page.goto(this.service.loginUrl);
@@ -235,12 +241,28 @@ export class ServiceSession {
235
241
  */
236
242
  export class SimpleServiceSession extends ServiceSession {
237
243
  apiCredentials = null;
244
+ /**
245
+ * What the session has extracted so far, or null while the login phase is
246
+ * still going.
247
+ *
248
+ * Exists for the tests, and they are its only callers: a real login goes
249
+ * through {@link login}, which returns the credentials once the phase
250
+ * completes. It is public rather than protected because the alternative is
251
+ * what the tests did before — casting past `protected` to read the field —
252
+ * which typechecks forever and quietly stops meaning anything the moment the
253
+ * internals change.
254
+ */
255
+ get capturedCredentials() {
256
+ return this.apiCredentials;
257
+ }
238
258
  onResponse(response) {
239
259
  if (this.apiCredentials !== null) {
240
- return;
260
+ return Promise.resolve();
241
261
  }
242
- this.getApiCredentialsFromResponse(response)
262
+ return this.getApiCredentialsFromResponse(response)
243
263
  .then((credentials) => {
264
+ // Another response may have produced credentials while this one was
265
+ // being read.
244
266
  if (this.apiCredentials === null && credentials !== null) {
245
267
  this.apiCredentials = credentials;
246
268
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/services/core/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/services/core/base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * What a generic browser login flow is, and how its parameters are read.
3
+ *
4
+ * A built-in service implements its login in code. A registered service picks a
5
+ * flow by name and supplies parameters as JSON, so new flows become available to
6
+ * every registered service without the CLI knowing anything about them.
7
+ *
8
+ * Three things are involved, and they are deliberately distinct:
9
+ *
10
+ * - a **flow class** is a kind of automation, with a name and a parameter
11
+ * schema — {@link LoginFlowClass};
12
+ * - a **flow** is one configuration of that kind, holding validated parameters
13
+ * and able to create sessions — {@link LoginFlow};
14
+ * - a **session** is a single run of one, created per login and discarded
15
+ * afterwards — `ServiceSession`.
16
+ *
17
+ * The parameters are validated long before a login happens (when a service is
18
+ * registered, or when config.json is read), which is why a flow rather than a
19
+ * session is what a registered service holds on to.
20
+ *
21
+ * The flows themselves are listed in `registry`, which imports them.
22
+ * Keeping that list out of this module is what lets a flow import from here
23
+ * without the two forming a cycle.
24
+ */
25
+ import type { ZodType, ZodTypeAny } from 'zod';
26
+ import { Service, type ServiceSession } from '../base.js';
27
+ /**
28
+ * Thrown when the parameters stored for a login flow do not match its schema.
29
+ */
30
+ export declare class LoginFlowParamsInvalidError extends Error {
31
+ constructor(flowName: string, detail: string);
32
+ }
33
+ /**
34
+ * A generic browser login that a user-registered service can opt into,
35
+ * configured with the parameters that service was registered with.
36
+ *
37
+ * A built-in service implements its login in code. A registered service picks a
38
+ * flow by name and supplies parameters as JSON, so new flows become available to
39
+ * every registered service without the CLI knowing anything about them.
40
+ */
41
+ export interface LoginFlow {
42
+ /** Sentence describing this configuration, for `services info`. */
43
+ describe(loginUrl: string): string;
44
+ createSession(service: Service, appNamePrefix: string): ServiceSession;
45
+ }
46
+ /**
47
+ * The class side of a flow: the kind of automation, before anyone configures
48
+ * it. Its instances are the configured flows.
49
+ *
50
+ * The metadata has to be static, since flows are listed and described before
51
+ * any parameters exist — and TypeScript has no `abstract static`, so this
52
+ * interface is what holds a flow class to declaring it. A flow states the
53
+ * obligation with `satisfies LoginFlowClass`; the registry checks it again by
54
+ * being typed as an array of these.
55
+ */
56
+ export interface LoginFlowClass {
57
+ new (params: unknown): LoginFlow;
58
+ /** Value of `--login-flow`. Not `name`, which every class already has. */
59
+ readonly flowName: string;
60
+ /** One-line explanation, listed by the CLI when the flow name is wrong. */
61
+ readonly summary: string;
62
+ /** Reference documentation, shown by `services register --help`. */
63
+ readonly details: string;
64
+ readonly paramsSchema: ZodTypeAny;
65
+ }
66
+ /**
67
+ * Validate the parameters a flow was registered with, against the flow's own
68
+ * schema. Inference gives back the schema's type, so a flow storing the result
69
+ * cannot disagree with the schema it declared.
70
+ */
71
+ export declare function parseLoginFlowParams<Params>(flowClass: {
72
+ readonly flowName: string;
73
+ readonly paramsSchema: ZodType<Params>;
74
+ }, rawParams: unknown): Params;
75
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../../src/services/core/loginFlows/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC/C,OAAO,EAAwB,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhF;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI7C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc,CAAC;CACxE;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EACzC,SAAS,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,EAChF,SAAS,EAAE,OAAO,GACjB,MAAM,CAMR"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * What a generic browser login flow is, and how its parameters are read.
3
+ *
4
+ * A built-in service implements its login in code. A registered service picks a
5
+ * flow by name and supplies parameters as JSON, so new flows become available to
6
+ * every registered service without the CLI knowing anything about them.
7
+ *
8
+ * Three things are involved, and they are deliberately distinct:
9
+ *
10
+ * - a **flow class** is a kind of automation, with a name and a parameter
11
+ * schema — {@link LoginFlowClass};
12
+ * - a **flow** is one configuration of that kind, holding validated parameters
13
+ * and able to create sessions — {@link LoginFlow};
14
+ * - a **session** is a single run of one, created per login and discarded
15
+ * afterwards — `ServiceSession`.
16
+ *
17
+ * The parameters are validated long before a login happens (when a service is
18
+ * registered, or when config.json is read), which is why a flow rather than a
19
+ * session is what a registered service holds on to.
20
+ *
21
+ * The flows themselves are listed in `registry`, which imports them.
22
+ * Keeping that list out of this module is what lets a flow import from here
23
+ * without the two forming a cycle.
24
+ */
25
+ import { describeSchemaIssues } from '../base.js';
26
+ /**
27
+ * Thrown when the parameters stored for a login flow do not match its schema.
28
+ */
29
+ export class LoginFlowParamsInvalidError extends Error {
30
+ constructor(flowName, detail) {
31
+ super(`Invalid parameters for login flow '${flowName}': ${detail}`);
32
+ this.name = 'LoginFlowParamsInvalidError';
33
+ }
34
+ }
35
+ /**
36
+ * Validate the parameters a flow was registered with, against the flow's own
37
+ * schema. Inference gives back the schema's type, so a flow storing the result
38
+ * cannot disagree with the schema it declared.
39
+ */
40
+ export function parseLoginFlowParams(flowClass, rawParams) {
41
+ const result = flowClass.paramsSchema.safeParse(rawParams ?? {});
42
+ if (!result.success) {
43
+ throw new LoginFlowParamsInvalidError(flowClass.flowName, describeSchemaIssues(result.error));
44
+ }
45
+ return result.data;
46
+ }
47
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../../src/services/core/loginFlows/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,oBAAoB,EAAgC,MAAM,YAAY,CAAC;AAEhF;;GAEG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,QAAgB,EAAE,MAAc;QAC1C,KAAK,CAAC,sCAAsC,QAAQ,MAAM,MAAM,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAqCD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAAgF,EAChF,SAAkB;IAElB,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,2BAA2B,CAAC,SAAS,CAAC,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * A generic browser login that works for any cookie-authenticated service:
3
+ * open a URL, watch the `Set-Cookie` headers of the responses that follow, and
4
+ * capture named cookies as the credentials.
5
+ *
6
+ * The cookie mechanics — reading `Set-Cookie`, deciding where a cookie applies,
7
+ * writing a `Cookie` header — are RFC 6265 and not specific to this flow, but
8
+ * they stay private to it: nothing else needs them, and behind the LoginFlow
9
+ * interface nobody has to care how this flow works. If cookie handling is ever
10
+ * wanted elsewhere, this is the part to lift back out into a module of its own.
11
+ *
12
+ * The flow interprets the registered parameters; the session it creates holds
13
+ * the cookies of one login.
14
+ *
15
+ * Nothing here is service-specific — the cookie names come from whoever
16
+ * registered the service, as the parameters of the `cookie-capture` login flow.
17
+ */
18
+ import { z } from 'zod';
19
+ import { Service, type ServiceSession } from '../base.js';
20
+ import { type LoginFlow } from './base.js';
21
+ /**
22
+ * The flow. Its statics are the kind of automation — what `--login-flow`
23
+ * selects — and an instance is that kind configured with one service's
24
+ * parameters, ready to create a session per login.
25
+ */
26
+ export declare class CookieCaptureLoginFlow implements LoginFlow {
27
+ /** Value of `--login-flow`. Not `name`, which every class already has. */
28
+ static readonly flowName = "cookie-capture";
29
+ static readonly summary = "Open the login URL and capture named session cookies as they are set.";
30
+ static readonly details: string;
31
+ static readonly paramsSchema: z.ZodObject<{
32
+ /** Cookie names to capture. The login completes once all of them exist. */
33
+ cookieKeys: z.ZodArray<z.ZodString, "many">;
34
+ /**
35
+ * URL the cookies must apply to. Defaults to the service's login URL, which
36
+ * is right unless sign-in happens on a different host than the API.
37
+ */
38
+ cookieUrl: z.ZodOptional<z.ZodString>;
39
+ }, "strict", z.ZodTypeAny, {
40
+ cookieKeys: string[];
41
+ cookieUrl?: string | undefined;
42
+ }, {
43
+ cookieKeys: string[];
44
+ cookieUrl?: string | undefined;
45
+ }>;
46
+ private readonly params;
47
+ constructor(rawParams: unknown);
48
+ describe(loginUrl: string): string;
49
+ /**
50
+ * The cookies are looked for wherever they would be sent: the page the login
51
+ * starts from, unless the parameters name somewhere else.
52
+ */
53
+ createSession(service: Service, appNamePrefix: string): ServiceSession;
54
+ }
55
+ //# sourceMappingURL=cookieCapture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookieCapture.d.ts","sourceRoot":"","sources":["../../../../../src/services/core/loginFlows/cookieCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAwB,KAAK,SAAS,EAAuB,MAAM,WAAW,CAAC;AA8NtF;;;;GAIG;AACH,qBAAa,sBAAuB,YAAW,SAAS;IACtD,0EAA0E;IAC1E,MAAM,CAAC,QAAQ,CAAC,QAAQ,oBAAoB;IAE5C,MAAM,CAAC,QAAQ,CAAC,OAAO,2EAA2E;IAElG,MAAM,CAAC,QAAQ,CAAC,OAAO,SAoBV;IAEb,MAAM,CAAC,QAAQ,CAAC,YAAY;QAvF1B,2EAA2E;;QAE3E;;;WAGG;;;;;;;;OAkFoD;IAEzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAEjC,SAAS,EAAE,OAAO;IAI9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQlC;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc;CAQvE"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * A generic browser login that works for any cookie-authenticated service:
3
+ * open a URL, watch the `Set-Cookie` headers of the responses that follow, and
4
+ * capture named cookies as the credentials.
5
+ *
6
+ * The cookie mechanics — reading `Set-Cookie`, deciding where a cookie applies,
7
+ * writing a `Cookie` header — are RFC 6265 and not specific to this flow, but
8
+ * they stay private to it: nothing else needs them, and behind the LoginFlow
9
+ * interface nobody has to care how this flow works. If cookie handling is ever
10
+ * wanted elsewhere, this is the part to lift back out into a module of its own.
11
+ *
12
+ * The flow interprets the registered parameters; the session it creates holds
13
+ * the cookies of one login.
14
+ *
15
+ * Nothing here is service-specific — the cookie names come from whoever
16
+ * registered the service, as the parameters of the `cookie-capture` login flow.
17
+ */
18
+ import { z } from 'zod';
19
+ import { RawCurlCredentials } from '../../../apiCredentials/base.js';
20
+ import { SimpleServiceSession } from '../base.js';
21
+ import { parseLoginFlowParams } from './base.js';
22
+ /**
23
+ * The path a cookie without a `Path` attribute applies to: the directory of the
24
+ * request path (RFC 6265 §5.1.4).
25
+ */
26
+ function defaultCookiePath(responseUrl) {
27
+ const path = responseUrl.pathname;
28
+ if (!path.startsWith('/')) {
29
+ return '/';
30
+ }
31
+ const lastSeparatorIndex = path.lastIndexOf('/');
32
+ return lastSeparatorIndex === 0 ? '/' : path.slice(0, lastSeparatorIndex);
33
+ }
34
+ function isExpired(expiresAttribute) {
35
+ const expiresAt = Date.parse(expiresAttribute);
36
+ return !Number.isNaN(expiresAt) && expiresAt <= Date.now();
37
+ }
38
+ /**
39
+ * Parse one `Set-Cookie` header value, as sent by the response at
40
+ * `responseUrl`. Returns null when it is not a usable cookie definition at all.
41
+ */
42
+ function parseSetCookieHeader(headerValue, responseUrl) {
43
+ const [nameValuePair = '', ...attributeParts] = headerValue.split(';');
44
+ const separatorIndex = nameValuePair.indexOf('=');
45
+ if (separatorIndex <= 0) {
46
+ return null;
47
+ }
48
+ const name = nameValuePair.slice(0, separatorIndex).trim();
49
+ const value = nameValuePair.slice(separatorIndex + 1).trim();
50
+ let domain = responseUrl.hostname.toLowerCase();
51
+ let path = defaultCookiePath(responseUrl);
52
+ // An empty value is how a cookie is cleared without an explicit expiry.
53
+ let isDeletion = value === '';
54
+ for (const attributePart of attributeParts) {
55
+ const attributeSeparatorIndex = attributePart.indexOf('=');
56
+ const attributeName = (attributeSeparatorIndex === -1
57
+ ? attributePart
58
+ : attributePart.slice(0, attributeSeparatorIndex))
59
+ .trim()
60
+ .toLowerCase();
61
+ const attributeValue = attributeSeparatorIndex === -1 ? '' : attributePart.slice(attributeSeparatorIndex + 1).trim();
62
+ if (attributeName === 'domain' && attributeValue !== '') {
63
+ domain = attributeValue.replace(/^\./, '').toLowerCase();
64
+ }
65
+ else if (attributeName === 'path' && attributeValue.startsWith('/')) {
66
+ path = attributeValue;
67
+ }
68
+ else if (attributeName === 'max-age' && Number(attributeValue) <= 0) {
69
+ isDeletion = true;
70
+ }
71
+ else if (attributeName === 'expires' && isExpired(attributeValue)) {
72
+ isDeletion = true;
73
+ }
74
+ }
75
+ return { name, value, domain, path, isDeletion };
76
+ }
77
+ /**
78
+ * Whether a browser would send this cookie to the given URL: the URL's host is
79
+ * the cookie's domain or below it, and its path is under the cookie's path.
80
+ */
81
+ function doesCookieApplyTo(cookie, url) {
82
+ const host = url.hostname.toLowerCase();
83
+ if (host !== cookie.domain && !host.endsWith(`.${cookie.domain}`)) {
84
+ return false;
85
+ }
86
+ const path = url.pathname === '' ? '/' : url.pathname;
87
+ return path.startsWith(cookie.path);
88
+ }
89
+ /**
90
+ * Identity of a cookie in the jar. The same name can be set more than once
91
+ * under different scopes, and a browser then sends all of them, so a cookie is
92
+ * only superseded by one of matching name, domain and path.
93
+ */
94
+ function cookieScopeKey(cookie) {
95
+ return `${cookie.name}\n${cookie.domain}\n${cookie.path}`;
96
+ }
97
+ /**
98
+ * The cookies that would be sent to one URL, built up from the `Set-Cookie`
99
+ * headers of the responses observed so far.
100
+ *
101
+ * Only cookies that apply to the jar's URL are kept, so cookies picked up along
102
+ * the way — from an identity provider on another domain, say — are discarded as
103
+ * they arrive.
104
+ */
105
+ class CookieJar {
106
+ url;
107
+ cookiesByScope = new Map();
108
+ constructor(url) {
109
+ this.url = url;
110
+ }
111
+ /**
112
+ * Take in the `Set-Cookie` headers of one response: cookies it sets are
113
+ * recorded, and cookies it clears are dropped.
114
+ */
115
+ accept(setCookieHeaderValues, responseUrl) {
116
+ for (const headerValue of setCookieHeaderValues) {
117
+ const cookie = parseSetCookieHeader(headerValue, responseUrl);
118
+ if (cookie === null || !doesCookieApplyTo(cookie, this.url)) {
119
+ continue;
120
+ }
121
+ if (cookie.isDeletion) {
122
+ this.cookiesByScope.delete(cookieScopeKey(cookie));
123
+ }
124
+ else {
125
+ this.cookiesByScope.set(cookieScopeKey(cookie), cookie);
126
+ }
127
+ }
128
+ }
129
+ has(name) {
130
+ return [...this.cookiesByScope.values()].some((cookie) => cookie.name === name);
131
+ }
132
+ /**
133
+ * The cookies of the given names. A name can appear more than once — set both
134
+ * host-only and domain-wide, say — and a browser sends every one of them.
135
+ */
136
+ cookiesNamed(names) {
137
+ return [...this.cookiesByScope.values()]
138
+ .filter((cookie) => names.includes(cookie.name))
139
+ .map((cookie) => ({ name: cookie.name, value: cookie.value }));
140
+ }
141
+ }
142
+ /**
143
+ * Render cookies as the value of a single `Cookie` header.
144
+ *
145
+ * One header carrying every pair separated by `'; '` is the only portable
146
+ * form: RFC 6265 has the user agent send one `Cookie` header, and servers that
147
+ * see several header lines commonly read just the first.
148
+ */
149
+ function formatCookieHeaderValue(cookies) {
150
+ return cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; ');
151
+ }
152
+ const CookieCaptureParamsSchema = z
153
+ .object({
154
+ /** Cookie names to capture. The login completes once all of them exist. */
155
+ cookieKeys: z.array(z.string().min(1)).min(1),
156
+ /**
157
+ * URL the cookies must apply to. Defaults to the service's login URL, which
158
+ * is right unless sign-in happens on a different host than the API.
159
+ */
160
+ cookieUrl: z.string().url().optional(),
161
+ })
162
+ .strict();
163
+ /** Store captured cookies the way `latchkey auth set -H` would. */
164
+ function buildCookieCredentials(cookies) {
165
+ return new RawCurlCredentials(['-H', `Cookie: ${formatCookieHeaderValue(cookies)}`]);
166
+ }
167
+ function setCookieHeaderValues(headers) {
168
+ return headers
169
+ .filter((header) => header.name.toLowerCase() === 'set-cookie')
170
+ .map((header) => header.value);
171
+ }
172
+ /**
173
+ * One run of the flow. A jar remembers the cookies as responses arrive; all
174
+ * this adds is which names the service asked for, and the rule that the login
175
+ * is done once every one of them has turned up.
176
+ */
177
+ class CookieCaptureSession extends SimpleServiceSession {
178
+ jar;
179
+ cookieKeys;
180
+ constructor(service, appNamePrefix, cookieUrl, cookieKeys) {
181
+ super(service, appNamePrefix);
182
+ this.jar = new CookieJar(cookieUrl);
183
+ this.cookieKeys = cookieKeys;
184
+ }
185
+ async getApiCredentialsFromResponse(response) {
186
+ this.jar.accept(setCookieHeaderValues(await response.headersArray()), new URL(response.url()));
187
+ if (!this.cookieKeys.every((cookieKey) => this.jar.has(cookieKey))) {
188
+ return null;
189
+ }
190
+ return buildCookieCredentials(this.jar.cookiesNamed(this.cookieKeys));
191
+ }
192
+ }
193
+ /**
194
+ * The flow. Its statics are the kind of automation — what `--login-flow`
195
+ * selects — and an instance is that kind configured with one service's
196
+ * parameters, ready to create a session per login.
197
+ */
198
+ export class CookieCaptureLoginFlow {
199
+ /** Value of `--login-flow`. Not `name`, which every class already has. */
200
+ static flowName = 'cookie-capture';
201
+ static summary = 'Open the login URL and capture named session cookies as they are set.';
202
+ static details = [
203
+ 'Parameters:',
204
+ ' cookieKeys Names of the cookies to capture. Required, at least one. The',
205
+ ' login finishes once every one of them has been set, and they',
206
+ ' are stored together as a single "Cookie: a=1; b=2" header.',
207
+ ' cookieUrl Full URL, including the scheme, that the cookies must apply',
208
+ ' to. Defaults to the login URL. Set it when signing in happens',
209
+ ' on a different host than the API.',
210
+ '',
211
+ 'The cookies are read from the Set-Cookie headers of the responses that',
212
+ 'arrive while the user signs in, so a cookie that only a page script sets is',
213
+ 'not seen, and neither is one that an already signed-in session never sends',
214
+ 'again.',
215
+ '',
216
+ 'Example:',
217
+ ' $ latchkey services register my-intranet \\',
218
+ ' --base-api-url="https://intranet.example.com/api/" \\',
219
+ ' --login-url="https://intranet.example.com/login" \\',
220
+ ' --login-flow=cookie-capture \\',
221
+ ' --login-flow-params=\'{"cookieKeys": ["sessionid", "csrftoken"]}\'',
222
+ ].join('\n');
223
+ static paramsSchema = CookieCaptureParamsSchema;
224
+ params;
225
+ constructor(rawParams) {
226
+ this.params = parseLoginFlowParams(CookieCaptureLoginFlow, rawParams);
227
+ }
228
+ describe(loginUrl) {
229
+ const quotedKeys = this.params.cookieKeys.map((cookieKey) => `'${cookieKey}'`).join(', ');
230
+ return (`\`latchkey auth browser\` opens ${loginUrl} and stores the ${quotedKeys} ` +
231
+ `cookies of ${this.params.cookieUrl ?? loginUrl} as the credentials once they are set.`);
232
+ }
233
+ /**
234
+ * The cookies are looked for wherever they would be sent: the page the login
235
+ * starts from, unless the parameters name somewhere else.
236
+ */
237
+ createSession(service, appNamePrefix) {
238
+ return new CookieCaptureSession(service, appNamePrefix, new URL(this.params.cookieUrl ?? service.loginUrl), this.params.cookieKeys);
239
+ }
240
+ }
241
+ // TypeScript has no `static implements`, so this is where the class side of the
242
+ // flow is checked. The registry checks it again, but the error lands here.
243
+ CookieCaptureLoginFlow;
244
+ //# sourceMappingURL=cookieCapture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookieCapture.js","sourceRoot":"","sources":["../../../../../src/services/core/loginFlows/cookieCapture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The list of generic browser login flows, and looking one up by the name
3
+ * `--login-flow` takes.
4
+ *
5
+ * This is the only module that knows which flows exist. What a flow *is* lives
6
+ * in `base`, which the flows themselves import; keeping the list separate is
7
+ * what stops that from being a cycle.
8
+ */
9
+ import type { LoginFlow, LoginFlowClass } from './base.js';
10
+ export declare const LOGIN_FLOWS: readonly LoginFlowClass[];
11
+ export declare class UnknownLoginFlowError extends Error {
12
+ constructor(name: string);
13
+ }
14
+ /**
15
+ * Look up a flow class by the name `--login-flow` takes, and configure it with
16
+ * the given parameters.
17
+ *
18
+ * Throws {@link UnknownLoginFlowError}, or `LoginFlowParamsInvalidError` from
19
+ * the flow's own validation; callers decide what an unusable flow means for
20
+ * them (the CLI rejects the registration, loading a stored service drops just
21
+ * the flow).
22
+ */
23
+ export declare function resolveLoginFlow(name: string, params: unknown): LoginFlow;
24
+ /**
25
+ * The reference documentation for every registered flow, for
26
+ * `latchkey services register --help`. Generated from the registry, so a flow
27
+ * added later documents itself without the CLI knowing anything about it.
28
+ */
29
+ export declare function formatLoginFlowsHelp(): string;
30
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../src/services/core/loginFlows/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3D,eAAO,MAAM,WAAW,EAAE,SAAS,cAAc,EAA6B,CAAC;AAE/E,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,IAAI,EAAE,MAAM;CAOzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,CAMzE;AASD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAa7C"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The list of generic browser login flows, and looking one up by the name
3
+ * `--login-flow` takes.
4
+ *
5
+ * This is the only module that knows which flows exist. What a flow *is* lives
6
+ * in `base`, which the flows themselves import; keeping the list separate is
7
+ * what stops that from being a cycle.
8
+ */
9
+ import { CookieCaptureLoginFlow } from './cookieCapture.js';
10
+ export const LOGIN_FLOWS = [CookieCaptureLoginFlow];
11
+ export class UnknownLoginFlowError extends Error {
12
+ constructor(name) {
13
+ super(`Unknown login flow '${name}'. Available flows: ` +
14
+ `${LOGIN_FLOWS.map((flowClass) => flowClass.flowName).join(', ')}.`);
15
+ this.name = 'UnknownLoginFlowError';
16
+ }
17
+ }
18
+ /**
19
+ * Look up a flow class by the name `--login-flow` takes, and configure it with
20
+ * the given parameters.
21
+ *
22
+ * Throws {@link UnknownLoginFlowError}, or `LoginFlowParamsInvalidError` from
23
+ * the flow's own validation; callers decide what an unusable flow means for
24
+ * them (the CLI rejects the registration, loading a stored service drops just
25
+ * the flow).
26
+ */
27
+ export function resolveLoginFlow(name, params) {
28
+ const flowClass = LOGIN_FLOWS.find((candidate) => candidate.flowName === name);
29
+ if (flowClass === undefined) {
30
+ throw new UnknownLoginFlowError(name);
31
+ }
32
+ return new flowClass(params);
33
+ }
34
+ function indent(text, spaces) {
35
+ return text
36
+ .split('\n')
37
+ .map((line) => (line === '' ? '' : `${spaces}${line}`))
38
+ .join('\n');
39
+ }
40
+ /**
41
+ * The reference documentation for every registered flow, for
42
+ * `latchkey services register --help`. Generated from the registry, so a flow
43
+ * added later documents itself without the CLI knowing anything about it.
44
+ */
45
+ export function formatLoginFlowsHelp() {
46
+ const sections = LOGIN_FLOWS.map((flowClass) => ` ${flowClass.flowName}\n${indent(flowClass.summary, ' ')}\n\n` +
47
+ indent(flowClass.details, ' '));
48
+ return [
49
+ 'Login flows:',
50
+ ' Each login flow is configured by a JSON object supplied by',
51
+ ' --login-flow-params.',
52
+ '',
53
+ ...sections,
54
+ ].join('\n');
55
+ }
56
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../../src/services/core/loginFlows/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,MAAM,CAAC,MAAM,WAAW,GAA8B,CAAC,sBAAsB,CAAC,CAAC;AAE/E,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,IAAY;QACtB,KAAK,CACH,uBAAuB,IAAI,sBAAsB;YAC/C,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACtE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAe;IAC5D,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC;IAC/E,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,MAAc;IAC1C,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC;SACtD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAC9B,CAAC,SAAS,EAAE,EAAE,CACZ,KAAK,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM;QACnE,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CACpC,CAAC;IACF,OAAO;QACL,cAAc;QACd,8DAA8D;QAC9D,wBAAwB;QACxB,EAAE;QACF,GAAG,QAAQ;KACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}