@zapier/zapier-sdk 0.50.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/api/auth.d.ts +1 -6
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +34 -27
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +3 -2
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/schemas.d.ts +3 -3
- package/dist/auth.d.ts +13 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +95 -11
- package/dist/experimental.cjs +167 -29
- package/dist/experimental.d.mts +2 -2
- package/dist/experimental.d.ts +26 -26
- package/dist/experimental.mjs +166 -30
- package/dist/{index-BQ2ii0Bs.d.mts → index-C52BjTXh.d.mts} +109 -2
- package/dist/{index-BQ2ii0Bs.d.ts → index-C52BjTXh.d.ts} +109 -2
- package/dist/index.cjs +167 -29
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.mjs +166 -30
- package/dist/plugins/apps/index.d.ts +2 -2
- package/dist/plugins/deprecated/inputFields.d.ts +18 -18
- package/dist/plugins/getAction/index.d.ts +6 -6
- package/dist/plugins/getAction/schemas.d.ts +4 -4
- package/dist/plugins/getActionInputFieldsSchema/index.d.ts +5 -5
- package/dist/plugins/getActionInputFieldsSchema/schemas.d.ts +4 -4
- package/dist/plugins/listActionInputFieldChoices/index.d.ts +5 -5
- package/dist/plugins/listActionInputFieldChoices/schemas.d.ts +4 -4
- package/dist/plugins/listActionInputFields/index.d.ts +5 -5
- package/dist/plugins/listActionInputFields/schemas.d.ts +4 -4
- package/dist/plugins/listActions/index.d.ts +3 -3
- package/dist/plugins/listActions/schemas.d.ts +4 -4
- package/dist/plugins/runAction/index.d.ts +5 -5
- package/dist/plugins/runAction/schemas.d.ts +4 -4
- package/dist/plugins/triggers/getTriggerInputFieldsSchema/index.d.ts +2 -2
- package/dist/plugins/triggers/listTriggerInputFieldChoices/index.d.ts +2 -2
- package/dist/plugins/triggers/listTriggerInputFields/index.d.ts +2 -2
- package/dist/schemas/Action.d.ts +1 -1
- package/dist/sdk.d.ts +52 -52
- package/dist/types/properties.d.ts +1 -1
- package/dist/utils/telemetry.d.ts +11 -0
- package/dist/utils/telemetry.d.ts.map +1 -0
- package/dist/utils/telemetry.js +19 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @zapier/zapier-sdk
|
|
2
2
|
|
|
3
|
+
## 0.51.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ef1c97d: Default SDK auth to client credentials
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- f5a734d: Updated the experimental Triggers notice in all three package READMEs to clarify that the feature is in closed beta, with a link to contact us for access.
|
|
12
|
+
|
|
3
13
|
## 0.50.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1792,7 +1792,7 @@ const result = await zapier.updateTableRecords({
|
|
|
1792
1792
|
|
|
1793
1793
|
### Triggers (Experimental)
|
|
1794
1794
|
|
|
1795
|
-
>
|
|
1795
|
+
> ⚠️ **Closed beta.** Import from `"@zapier/zapier-sdk/experimental"` to use these methods. Methods and behavior may change. [Contact us](https://npsup.zapier.app/contact-us?product=Zapier%20SDK) to request access.
|
|
1796
1796
|
|
|
1797
1797
|
#### `ackTriggerInboxMessages` 🧪 _experimental_
|
|
1798
1798
|
|
package/dist/api/auth.d.ts
CHANGED
|
@@ -6,12 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function isJwt(token: string): boolean;
|
|
8
8
|
export declare function getAuthorizationHeader(token: string): string;
|
|
9
|
-
/**
|
|
10
|
-
* Extract user IDs from JWT token
|
|
11
|
-
* Decodes the JWT payload and extracts customuser_id and account_id
|
|
12
|
-
* Handles nested JWTs for service tokens
|
|
13
|
-
* Returns null values on any failure (silent-by-design)
|
|
14
|
-
*/
|
|
9
|
+
/** Never throws — an auth decode error must not take down request telemetry. */
|
|
15
10
|
export declare function extractUserIdsFromJwt(token: string): {
|
|
16
11
|
customuser_id: number | null;
|
|
17
12
|
account_id: number | null;
|
package/dist/api/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAW5C;AAaD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAW5C;AAaD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;AA8BD,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG;IACpD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAmBA"}
|
package/dist/api/auth.js
CHANGED
|
@@ -33,38 +33,45 @@ export function getAuthorizationHeader(token) {
|
|
|
33
33
|
// Default to Bearer for other token types
|
|
34
34
|
return `Bearer ${token}`;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Decodes the JWT payload and extracts customuser_id and account_id
|
|
39
|
-
* Handles nested JWTs for service tokens
|
|
40
|
-
* Returns null values on any failure (silent-by-design)
|
|
41
|
-
*/
|
|
42
|
-
export function extractUserIdsFromJwt(token) {
|
|
36
|
+
// Handles nested service-JWT shape (`sub_type: "service"` with `njwt`). Lenient — falls back to outer payload on nested parse failure.
|
|
37
|
+
function readJwtPayload(token) {
|
|
43
38
|
const parts = parseJwt(token);
|
|
44
|
-
if (!parts)
|
|
45
|
-
return
|
|
46
|
-
|
|
39
|
+
if (!parts)
|
|
40
|
+
return null;
|
|
41
|
+
let payload;
|
|
47
42
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf-8"));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (payload["sub_type"] === "service" &&
|
|
49
|
+
typeof payload["njwt"] === "string") {
|
|
50
|
+
const nestedParts = parseJwt(payload["njwt"]);
|
|
51
|
+
if (nestedParts) {
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(Buffer.from(nestedParts[1], "base64url").toString("utf-8"));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Fall through to outer payload.
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
const accountId = actualPayload["zap:acc"] != null
|
|
57
|
-
? parseInt(String(actualPayload["zap:acc"]), 10)
|
|
58
|
-
: null;
|
|
59
|
-
const customUserId = actualPayload.sub_type === "customuser" && actualPayload.sub != null
|
|
60
|
-
? parseInt(String(actualPayload.sub), 10)
|
|
61
|
-
: null;
|
|
62
|
-
return {
|
|
63
|
-
customuser_id: customUserId !== null && !isNaN(customUserId) ? customUserId : null,
|
|
64
|
-
account_id: accountId !== null && !isNaN(accountId) ? accountId : null,
|
|
65
|
-
};
|
|
66
59
|
}
|
|
67
|
-
|
|
60
|
+
return payload;
|
|
61
|
+
}
|
|
62
|
+
/** Never throws — an auth decode error must not take down request telemetry. */
|
|
63
|
+
export function extractUserIdsFromJwt(token) {
|
|
64
|
+
const payload = readJwtPayload(token);
|
|
65
|
+
if (!payload) {
|
|
68
66
|
return { customuser_id: null, account_id: null };
|
|
69
67
|
}
|
|
68
|
+
const accRaw = payload["zap:acc"];
|
|
69
|
+
const accountId = accRaw != null ? parseInt(String(accRaw), 10) : null;
|
|
70
|
+
const customUserId = payload["sub_type"] === "customuser" && payload["sub"] != null
|
|
71
|
+
? parseInt(String(payload["sub"]), 10)
|
|
72
|
+
: null;
|
|
73
|
+
return {
|
|
74
|
+
customuser_id: customUserId !== null && !isNaN(customUserId) ? customUserId : null,
|
|
75
|
+
account_id: accountId !== null && !isNaN(accountId) ? accountId : null,
|
|
76
|
+
};
|
|
70
77
|
}
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAGjB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAGjB,MAAM,SAAS,CAAC;AA4jCjB,eAAO,MAAM,eAAe,GAAI,SAAS,gBAAgB,KAAG,SAW3D,CAAC"}
|
package/dist/api/client.js
CHANGED
|
@@ -625,8 +625,9 @@ class ZapierApiClient {
|
|
|
625
625
|
}
|
|
626
626
|
// Check if we have an auth token available
|
|
627
627
|
const wasMissingAuthToken = options.authRequired &&
|
|
628
|
-
(await this.getAuthToken({
|
|
629
|
-
|
|
628
|
+
(await this.getAuthToken({
|
|
629
|
+
requiredScopes: options.requiredScopes,
|
|
630
|
+
})) == null;
|
|
630
631
|
const response = await this.fetch(path, {
|
|
631
632
|
...options,
|
|
632
633
|
method,
|
package/dist/api/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
export type { ApiClient, ApiClientOptions, RequestOptions, PollOptions, DebugLogger, Action, Field, Choice, ActionExecutionResult, ActionField, ActionFieldChoice, NeedsRequest, NeedsResponse, Connection, ConnectionsResponse, Implementation, ImplementationsResponse, } from "./types";
|
|
9
9
|
import type { ApiClient } from "./types";
|
|
10
10
|
import type { Credentials } from "../types/credentials";
|
|
11
|
-
export { isJwt, getAuthorizationHeader } from "./auth";
|
|
11
|
+
export { isJwt, getAuthorizationHeader, extractUserIdsFromJwt } from "./auth";
|
|
12
12
|
export { createDebugLogger, createDebugFetch } from "./debug";
|
|
13
13
|
export { pollUntilComplete } from "./polling";
|
|
14
14
|
export { createZapierApi } from "./client";
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EAEV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,WAAW,EAEX,MAAM,EACN,KAAK,EACL,MAAM,EACN,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EAEV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,WAAW,EAEX,MAAM,EACN,KAAK,EACL,MAAM,EACN,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAG9E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAM3C,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC,GAAG,SAAS,CAsBZ"}
|
package/dist/api/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { ZAPIER_BASE_URL } from "../constants";
|
|
9
9
|
// Re-export authentication utilities
|
|
10
|
-
export { isJwt, getAuthorizationHeader } from "./auth";
|
|
10
|
+
export { isJwt, getAuthorizationHeader, extractUserIdsFromJwt } from "./auth";
|
|
11
11
|
// Re-export debug utilities
|
|
12
12
|
export { createDebugLogger, createDebugFetch } from "./debug";
|
|
13
13
|
// Re-export polling utilities
|
package/dist/api/schemas.d.ts
CHANGED
|
@@ -66,13 +66,13 @@ export declare const ActionSchema: z.ZodObject<{
|
|
|
66
66
|
id: z.ZodOptional<z.ZodString>;
|
|
67
67
|
type: z.ZodEnum<{
|
|
68
68
|
filter: "filter";
|
|
69
|
+
write: "write";
|
|
69
70
|
read: "read";
|
|
70
71
|
read_bulk: "read_bulk";
|
|
71
72
|
run: "run";
|
|
72
73
|
search: "search";
|
|
73
74
|
search_and_write: "search_and_write";
|
|
74
75
|
search_or_write: "search_or_write";
|
|
75
|
-
write: "write";
|
|
76
76
|
}>;
|
|
77
77
|
key: z.ZodString;
|
|
78
78
|
name: z.ZodString;
|
|
@@ -314,13 +314,13 @@ export declare const ImplementationSchema: z.ZodObject<{
|
|
|
314
314
|
id: z.ZodOptional<z.ZodString>;
|
|
315
315
|
type: z.ZodEnum<{
|
|
316
316
|
filter: "filter";
|
|
317
|
+
write: "write";
|
|
317
318
|
read: "read";
|
|
318
319
|
read_bulk: "read_bulk";
|
|
319
320
|
run: "run";
|
|
320
321
|
search: "search";
|
|
321
322
|
search_and_write: "search_and_write";
|
|
322
323
|
search_or_write: "search_or_write";
|
|
323
|
-
write: "write";
|
|
324
324
|
}>;
|
|
325
325
|
key: z.ZodString;
|
|
326
326
|
name: z.ZodString;
|
|
@@ -356,13 +356,13 @@ export declare const ImplementationsResponseSchema: z.ZodObject<{
|
|
|
356
356
|
id: z.ZodOptional<z.ZodString>;
|
|
357
357
|
type: z.ZodEnum<{
|
|
358
358
|
filter: "filter";
|
|
359
|
+
write: "write";
|
|
359
360
|
read: "read";
|
|
360
361
|
read_bulk: "read_bulk";
|
|
361
362
|
run: "run";
|
|
362
363
|
search: "search";
|
|
363
364
|
search_and_write: "search_and_write";
|
|
364
365
|
search_or_write: "search_or_write";
|
|
365
|
-
write: "write";
|
|
366
366
|
}>;
|
|
367
367
|
key: z.ZodString;
|
|
368
368
|
name: z.ZodString;
|
package/dist/auth.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @zapier/zapier-sdk-cli package (imported via its `./login` subpath).
|
|
10
10
|
*/
|
|
11
11
|
import type { EventCallback } from "./types/events";
|
|
12
|
-
import type { Credentials } from "./types/credentials";
|
|
12
|
+
import type { Credentials, ClientCredentialsObject } from "./types/credentials";
|
|
13
13
|
import { type ZapierCache } from "./cache";
|
|
14
14
|
export type { ZapierCache, ZapierCacheEntry, ZapierCacheSetOptions, } from "./cache";
|
|
15
15
|
export { createMemoryCache } from "./cache";
|
|
@@ -74,7 +74,18 @@ interface CliLoginOptions {
|
|
|
74
74
|
};
|
|
75
75
|
debug?: boolean;
|
|
76
76
|
}
|
|
77
|
-
type CliLoginModule = typeof import("@zapier/zapier-sdk-cli/login")
|
|
77
|
+
type CliLoginModule = typeof import("@zapier/zapier-sdk-cli/login") & {
|
|
78
|
+
getActiveCredentials?: (options?: {
|
|
79
|
+
baseUrl?: string;
|
|
80
|
+
}) => {
|
|
81
|
+
clientId: string;
|
|
82
|
+
scopes: string[];
|
|
83
|
+
baseUrl?: string;
|
|
84
|
+
} | undefined;
|
|
85
|
+
getStoredClientCredentials?: (options?: {
|
|
86
|
+
baseUrl?: string;
|
|
87
|
+
}) => Promise<ClientCredentialsObject | undefined>;
|
|
88
|
+
};
|
|
78
89
|
/**
|
|
79
90
|
* Inject an already-loaded CLI login module so the SDK skips its dynamic import.
|
|
80
91
|
* This guarantees CLI and SDK share the same module instance in the same process.
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* @zapier/zapier-sdk-cli package (imported via its `./login` subpath).
|
|
10
10
|
*/
|
|
11
11
|
import { isClientCredentials, isPkceCredentials } from "./types/credentials";
|
|
12
|
+
import { ZapierAuthenticationError } from "./types/errors";
|
|
13
|
+
import { emitOnce } from "./utils/telemetry";
|
|
12
14
|
import { resolveCredentials, getClientIdFromCredentials } from "./credentials";
|
|
13
15
|
import { createMemoryCache } from "./cache";
|
|
14
16
|
const DEFAULT_AUTH_BASE_URL = "https://zapier.com";
|
|
@@ -61,8 +63,10 @@ async function resolveCache(options) {
|
|
|
61
63
|
if (cliLogin?.createCache) {
|
|
62
64
|
try {
|
|
63
65
|
const cache = cliLogin.createCache();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
if (cache) {
|
|
67
|
+
cachedDefaultCache = cache;
|
|
68
|
+
return cache;
|
|
69
|
+
}
|
|
66
70
|
}
|
|
67
71
|
catch {
|
|
68
72
|
// Fall through to in-memory if the CLI provider can't be constructed.
|
|
@@ -77,6 +81,12 @@ function entryIsValid(entry) {
|
|
|
77
81
|
return true;
|
|
78
82
|
return entry.expiresAt > Date.now() + TOKEN_EXPIRATION_BUFFER_MS;
|
|
79
83
|
}
|
|
84
|
+
async function readCachedToken(cacheKey, cache) {
|
|
85
|
+
const cached = await cache.get(cacheKey);
|
|
86
|
+
if (cached && entryIsValid(cached))
|
|
87
|
+
return cached.value;
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
80
90
|
/**
|
|
81
91
|
* Invalidate the cached token for a given client_credentials identity.
|
|
82
92
|
* Called on 401 so the next request re-exchanges. Clears both the
|
|
@@ -227,6 +237,23 @@ export function isCliLoginAvailable() {
|
|
|
227
237
|
return undefined;
|
|
228
238
|
return cachedCliLogin !== false;
|
|
229
239
|
}
|
|
240
|
+
function emitAuthResolved(onEvent, mechanism) {
|
|
241
|
+
if (onEvent) {
|
|
242
|
+
emitOnce(onEvent, {
|
|
243
|
+
type: "auth_resolved",
|
|
244
|
+
payload: { mechanism },
|
|
245
|
+
timestamp: Date.now(),
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async function getActiveCredentialsFromCli(baseUrl) {
|
|
250
|
+
const cliLogin = await getCliLogin();
|
|
251
|
+
return cliLogin?.getActiveCredentials?.({ baseUrl });
|
|
252
|
+
}
|
|
253
|
+
async function getStoredClientCredentialsFromCli(baseUrl) {
|
|
254
|
+
const cliLogin = await getCliLogin();
|
|
255
|
+
return cliLogin?.getStoredClientCredentials?.({ baseUrl });
|
|
256
|
+
}
|
|
230
257
|
/**
|
|
231
258
|
* Attempts to get a token from the CLI login package.
|
|
232
259
|
*
|
|
@@ -239,6 +266,47 @@ export async function getTokenFromCliLogin(options) {
|
|
|
239
266
|
return undefined;
|
|
240
267
|
return await cliLogin.getToken(options);
|
|
241
268
|
}
|
|
269
|
+
async function tryStoredClientCredentialToken(options) {
|
|
270
|
+
const activeCredential = await getActiveCredentialsFromCli(options.baseUrl);
|
|
271
|
+
if (!activeCredential)
|
|
272
|
+
return undefined;
|
|
273
|
+
const resolvedBaseUrl = activeCredential.baseUrl || options.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
274
|
+
const mergedScopes = mergeScopes(activeCredential.scopes.join(" "), options.requiredScopes);
|
|
275
|
+
const cacheKey = buildCacheKey({
|
|
276
|
+
clientId: activeCredential.clientId,
|
|
277
|
+
scopes: mergedScopes,
|
|
278
|
+
baseUrl: resolvedBaseUrl,
|
|
279
|
+
});
|
|
280
|
+
const cache = await resolveCache(options);
|
|
281
|
+
const pending = pendingExchanges.get(cacheKey);
|
|
282
|
+
if (pending)
|
|
283
|
+
return pending;
|
|
284
|
+
const cached = await readCachedToken(cacheKey, cache);
|
|
285
|
+
if (cached !== undefined) {
|
|
286
|
+
if (options.debug)
|
|
287
|
+
console.log(`[auth] Using cached token (clientId: ${activeCredential.clientId})`);
|
|
288
|
+
emitAuthResolved(options.onEvent, "client_credentials");
|
|
289
|
+
return cached;
|
|
290
|
+
}
|
|
291
|
+
const storedCredential = await getStoredClientCredentialsFromCli(resolvedBaseUrl);
|
|
292
|
+
if (!storedCredential) {
|
|
293
|
+
// Active credential pointer exists but the keychain secret is missing.
|
|
294
|
+
// Falling back to JWT would silently downgrade a migrated user; surface
|
|
295
|
+
// the broken state so they re-run login to recreate the secret.
|
|
296
|
+
await invalidateCachedToken({
|
|
297
|
+
clientId: activeCredential.clientId,
|
|
298
|
+
scopes: activeCredential.scopes,
|
|
299
|
+
baseUrl: resolvedBaseUrl,
|
|
300
|
+
cache: options.cache,
|
|
301
|
+
});
|
|
302
|
+
throw new ZapierAuthenticationError(`Stored client credential is missing its secret (clientId: ${activeCredential.clientId}). Run \`zapier-sdk login\` to recreate it.`);
|
|
303
|
+
}
|
|
304
|
+
if (options.debug)
|
|
305
|
+
console.log(`[auth] Using stored client credential (clientId: ${storedCredential.clientId})`);
|
|
306
|
+
const token = await resolveAuthTokenFromCredentials(storedCredential, options);
|
|
307
|
+
emitAuthResolved(options.onEvent, "client_credentials");
|
|
308
|
+
return token;
|
|
309
|
+
}
|
|
242
310
|
/**
|
|
243
311
|
* Resolves an auth token from wherever it can be found.
|
|
244
312
|
*
|
|
@@ -265,19 +333,28 @@ export async function resolveAuthToken(options = {}) {
|
|
|
265
333
|
if (credentials !== undefined) {
|
|
266
334
|
return resolveAuthTokenFromCredentials(credentials, options);
|
|
267
335
|
}
|
|
268
|
-
|
|
269
|
-
|
|
336
|
+
const storedToken = await tryStoredClientCredentialToken(options);
|
|
337
|
+
if (storedToken !== undefined)
|
|
338
|
+
return storedToken;
|
|
339
|
+
if (options.debug) {
|
|
340
|
+
console.log("[auth] Using JWT (no stored client credential found)");
|
|
341
|
+
}
|
|
342
|
+
const jwtToken = await getTokenFromCliLogin({
|
|
270
343
|
onEvent: options.onEvent,
|
|
271
344
|
fetch: options.fetch,
|
|
272
345
|
debug: options.debug,
|
|
273
346
|
});
|
|
347
|
+
if (jwtToken !== undefined) {
|
|
348
|
+
emitAuthResolved(options.onEvent, "jwt");
|
|
349
|
+
}
|
|
350
|
+
return jwtToken;
|
|
274
351
|
}
|
|
275
352
|
/**
|
|
276
353
|
* Resolve an auth token from resolved credentials.
|
|
277
354
|
*/
|
|
278
355
|
async function resolveAuthTokenFromCredentials(credentials, options) {
|
|
279
|
-
// String credentials are used directly as tokens
|
|
280
356
|
if (typeof credentials === "string") {
|
|
357
|
+
emitAuthResolved(options.onEvent, "token");
|
|
281
358
|
return credentials;
|
|
282
359
|
}
|
|
283
360
|
// Client credentials: exchange + cache through a pluggable cache
|
|
@@ -299,9 +376,12 @@ async function resolveAuthTokenFromCredentials(credentials, options) {
|
|
|
299
376
|
});
|
|
300
377
|
const cache = await resolveCache(options);
|
|
301
378
|
// Fast-path read
|
|
302
|
-
const cached = await
|
|
303
|
-
if (cached
|
|
304
|
-
|
|
379
|
+
const cached = await readCachedToken(cacheKey, cache);
|
|
380
|
+
if (cached !== undefined) {
|
|
381
|
+
if (options.debug) {
|
|
382
|
+
console.log(`[auth] Using cached token (clientId: ${clientId})`);
|
|
383
|
+
}
|
|
384
|
+
return cached;
|
|
305
385
|
}
|
|
306
386
|
// In-process dedup
|
|
307
387
|
const pending = pendingExchanges.get(cacheKey);
|
|
@@ -312,9 +392,13 @@ async function resolveAuthTokenFromCredentials(credentials, options) {
|
|
|
312
392
|
// cache under the lock and uses the first's token instead of firing
|
|
313
393
|
// another exchange.
|
|
314
394
|
const runLocked = async () => {
|
|
315
|
-
const recheck = await
|
|
316
|
-
if (recheck
|
|
317
|
-
|
|
395
|
+
const recheck = await readCachedToken(cacheKey, cache);
|
|
396
|
+
if (recheck !== undefined) {
|
|
397
|
+
if (options.debug) {
|
|
398
|
+
console.log(`[auth] Using cached token (clientId: ${clientId}, locked recheck)`);
|
|
399
|
+
}
|
|
400
|
+
return recheck;
|
|
401
|
+
}
|
|
318
402
|
const { accessToken, expiresIn } = await exchangeClientCredentials({
|
|
319
403
|
clientId: credentials.clientId,
|
|
320
404
|
clientSecret: credentials.clientSecret,
|