@zapier/zapier-sdk-cli 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/zapier-sdk.js +1 -1
- package/bin/zsdk.js +1 -1
- package/dist/cli.js +3 -5
- package/dist/commands/configPath.js +1 -1
- package/dist/commands/index.d.ts +4 -4
- package/dist/commands/index.js +4 -4
- package/dist/commands/login.js +2 -2
- package/dist/commands/logout.js +1 -1
- package/dist/commands/whoami.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/utils/auth/login.js +6 -7
- package/dist/utils/cli-generator.js +3 -3
- package/package.json +3 -3
- package/src/cli.ts +3 -5
- package/src/commands/configPath.ts +1 -1
- package/src/commands/index.ts +4 -4
- package/src/commands/login.ts +2 -2
- package/src/commands/logout.ts +1 -1
- package/src/commands/whoami.ts +7 -2
- package/src/utils/auth/login.ts +6 -7
- package/src/utils/cli-generator.ts +3 -3
- package/tsconfig.json +2 -2
- package/dist/utils/auth/ensureValidToken.d.ts +0 -7
- package/dist/utils/auth/ensureValidToken.js +0 -33
- package/dist/utils/auth/getAuthState.d.ts +0 -12
- package/dist/utils/auth/getAuthState.js +0 -17
- package/dist/utils/auth/getJWT.d.ts +0 -2
- package/dist/utils/auth/getJWT.js +0 -13
- package/dist/utils/auth/getLoggedInUser.d.ts +0 -6
- package/dist/utils/auth/getLoggedInUser.js +0 -47
- package/dist/utils/auth/logout.d.ts +0 -2
- package/dist/utils/auth/logout.js +0 -7
- package/dist/utils/auth/refreshJWT.d.ts +0 -2
- package/dist/utils/auth/refreshJWT.js +0 -33
- package/dist/utils/auth/updateLogin.d.ts +0 -7
- package/dist/utils/auth/updateLogin.js +0 -7
- package/dist/utils/config.d.ts +0 -2
- package/dist/utils/config.js +0 -2
- package/dist/utils/getConfigPath.d.ts +0 -1
- package/dist/utils/getConfigPath.js +0 -4
- package/src/utils/auth/ensureValidToken.ts +0 -35
- package/src/utils/auth/getAuthState.ts +0 -36
- package/src/utils/auth/getJWT.ts +0 -20
- package/src/utils/auth/getLoggedInUser.ts +0 -68
- package/src/utils/auth/logout.ts +0 -9
- package/src/utils/auth/refreshJWT.ts +0 -50
- package/src/utils/auth/updateLogin.ts +0 -19
- package/src/utils/config.ts +0 -3
- package/src/utils/getConfigPath.ts +0 -5
package/bin/zapier-sdk.js
CHANGED
package/bin/zsdk.js
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { createZapierSdk } from "@zapier/zapier-sdk";
|
|
4
|
-
import { generateCliCommands } from "./utils/cli-generator";
|
|
5
|
-
import {
|
|
6
|
-
import { createLoginCommand, createLogoutCommand, createWhoamiCommand, createConfigPathCommand, } from "./commands";
|
|
4
|
+
import { generateCliCommands } from "./utils/cli-generator.js";
|
|
5
|
+
import { createLoginCommand, createLogoutCommand, createWhoamiCommand, createConfigPathCommand, } from "./commands/index.js";
|
|
7
6
|
const program = new Command();
|
|
8
7
|
program
|
|
9
8
|
.name("zapier-sdk")
|
|
@@ -12,9 +11,8 @@ program
|
|
|
12
11
|
.option("--debug", "Enable debug logging");
|
|
13
12
|
// Check for debug flag early
|
|
14
13
|
const isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
|
|
15
|
-
// Create SDK instance
|
|
14
|
+
// Create SDK instance - automatically handles token resolution
|
|
16
15
|
const sdk = createZapierSdk({
|
|
17
|
-
getToken: ensureValidToken,
|
|
18
16
|
debug: isDebugMode,
|
|
19
17
|
});
|
|
20
18
|
// Add auth commands before generating SDK commands
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { getConfigPath } from "
|
|
2
|
+
import { getConfigPath } from "@zapier/zapier-sdk";
|
|
3
3
|
export function createConfigPathCommand() {
|
|
4
4
|
return new Command("get-config-path")
|
|
5
5
|
.description("Show the path to the configuration file")
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createLoginCommand } from "./login";
|
|
2
|
-
export { createLogoutCommand } from "./logout";
|
|
3
|
-
export { createWhoamiCommand } from "./whoami";
|
|
4
|
-
export { createConfigPathCommand } from "./configPath";
|
|
1
|
+
export { createLoginCommand } from "./login.js";
|
|
2
|
+
export { createLogoutCommand } from "./logout.js";
|
|
3
|
+
export { createWhoamiCommand } from "./whoami.js";
|
|
4
|
+
export { createConfigPathCommand } from "./configPath.js";
|
package/dist/commands/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createLoginCommand } from "./login";
|
|
2
|
-
export { createLogoutCommand } from "./logout";
|
|
3
|
-
export { createWhoamiCommand } from "./whoami";
|
|
4
|
-
export { createConfigPathCommand } from "./configPath";
|
|
1
|
+
export { createLoginCommand } from "./login.js";
|
|
2
|
+
export { createLogoutCommand } from "./logout.js";
|
|
3
|
+
export { createWhoamiCommand } from "./whoami.js";
|
|
4
|
+
export { createConfigPathCommand } from "./configPath.js";
|
package/dist/commands/login.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import login from "../utils/auth/login";
|
|
3
|
-
import getLoggedInUser from "
|
|
2
|
+
import login from "../utils/auth/login.js";
|
|
3
|
+
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
4
4
|
export function createLoginCommand() {
|
|
5
5
|
return new Command("login")
|
|
6
6
|
.description("Log in to Zapier to access your account")
|
package/dist/commands/logout.js
CHANGED
package/dist/commands/whoami.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import getLoggedInUser from "
|
|
2
|
+
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
3
|
+
import { spinPromise } from "../utils/spinner.js";
|
|
3
4
|
export function createWhoamiCommand() {
|
|
4
5
|
return new Command("whoami")
|
|
5
6
|
.description("Show current login status and user information")
|
|
6
7
|
.action(async () => {
|
|
7
8
|
try {
|
|
8
|
-
const user = await getLoggedInUser();
|
|
9
|
+
const user = await spinPromise(getLoggedInUser(), "Checking login status...");
|
|
9
10
|
console.log(`✅ Logged in as ${user.email} (Account ID: ${user.accountId})`);
|
|
10
11
|
}
|
|
11
12
|
catch {
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
CHANGED
package/dist/utils/auth/login.js
CHANGED
|
@@ -2,13 +2,12 @@ import open from "open";
|
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
import express from "express";
|
|
4
4
|
import pkceChallenge from "pkce-challenge";
|
|
5
|
-
import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, LOGIN_PORTS, LOGIN_TIMEOUT_MS, ZAPIER_BASE, } from "../constants";
|
|
6
|
-
import { spinPromise } from "../spinner";
|
|
7
|
-
import log from "../log";
|
|
8
|
-
import api from "../api/client";
|
|
9
|
-
import getCallablePromise from "../getCallablePromise";
|
|
10
|
-
import updateLogin from "
|
|
11
|
-
import logout from "./logout";
|
|
5
|
+
import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, LOGIN_PORTS, LOGIN_TIMEOUT_MS, ZAPIER_BASE, } from "../constants.js";
|
|
6
|
+
import { spinPromise } from "../spinner.js";
|
|
7
|
+
import log from "../log.js";
|
|
8
|
+
import api from "../api/client.js";
|
|
9
|
+
import getCallablePromise from "../getCallablePromise.js";
|
|
10
|
+
import { updateLogin, logout } from "@zapier/zapier-sdk";
|
|
12
11
|
const findAvailablePort = () => {
|
|
13
12
|
return new Promise((resolve, reject) => {
|
|
14
13
|
let portIndex = 0;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { hasResolver, isPositional } from "@zapier/zapier-sdk";
|
|
3
|
-
import { SchemaParameterResolver } from "./parameter-resolver";
|
|
4
|
-
import { createPager } from "./pager";
|
|
5
|
-
import { formatItemsFromSchema } from "./schema-formatter";
|
|
3
|
+
import { SchemaParameterResolver } from "./parameter-resolver.js";
|
|
4
|
+
import { createPager } from "./pager.js";
|
|
5
|
+
import { formatItemsFromSchema } from "./schema-formatter.js";
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
import util from "util";
|
|
8
8
|
// ============================================================================
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zapier/zapier-sdk-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Command line interface for Zapier SDK",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
8
|
"bin": {
|
|
@@ -22,7 +23,6 @@
|
|
|
22
23
|
"chalk": "^5.3.0",
|
|
23
24
|
"cli-table3": "^0.6.5",
|
|
24
25
|
"commander": "^12.0.0",
|
|
25
|
-
"conf": "^14.0.0",
|
|
26
26
|
"express": "^5.1.0",
|
|
27
27
|
"inquirer": "^12.6.3",
|
|
28
28
|
"jsonwebtoken": "^9.0.2",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ora": "^8.2.0",
|
|
31
31
|
"pkce-challenge": "^5.0.0",
|
|
32
32
|
"zod": "^3.25.67",
|
|
33
|
-
"@zapier/zapier-sdk": "0.
|
|
33
|
+
"@zapier/zapier-sdk": "0.3.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/express": "^5.0.3",
|
package/src/cli.ts
CHANGED
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { createZapierSdk } from "@zapier/zapier-sdk";
|
|
5
|
-
import { generateCliCommands } from "./utils/cli-generator";
|
|
6
|
-
import { ensureValidToken } from "./utils/auth/ensureValidToken";
|
|
5
|
+
import { generateCliCommands } from "./utils/cli-generator.js";
|
|
7
6
|
import {
|
|
8
7
|
createLoginCommand,
|
|
9
8
|
createLogoutCommand,
|
|
10
9
|
createWhoamiCommand,
|
|
11
10
|
createConfigPathCommand,
|
|
12
|
-
} from "./commands";
|
|
11
|
+
} from "./commands/index.js";
|
|
13
12
|
|
|
14
13
|
const program = new Command();
|
|
15
14
|
|
|
@@ -23,9 +22,8 @@ program
|
|
|
23
22
|
const isDebugMode =
|
|
24
23
|
process.env.DEBUG === "true" || process.argv.includes("--debug");
|
|
25
24
|
|
|
26
|
-
// Create SDK instance
|
|
25
|
+
// Create SDK instance - automatically handles token resolution
|
|
27
26
|
const sdk = createZapierSdk({
|
|
28
|
-
getToken: ensureValidToken,
|
|
29
27
|
debug: isDebugMode,
|
|
30
28
|
});
|
|
31
29
|
|
package/src/commands/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createLoginCommand } from "./login";
|
|
2
|
-
export { createLogoutCommand } from "./logout";
|
|
3
|
-
export { createWhoamiCommand } from "./whoami";
|
|
4
|
-
export { createConfigPathCommand } from "./configPath";
|
|
1
|
+
export { createLoginCommand } from "./login.js";
|
|
2
|
+
export { createLogoutCommand } from "./logout.js";
|
|
3
|
+
export { createWhoamiCommand } from "./whoami.js";
|
|
4
|
+
export { createConfigPathCommand } from "./configPath.js";
|
package/src/commands/login.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import login from "../utils/auth/login";
|
|
3
|
-
import getLoggedInUser from "
|
|
2
|
+
import login from "../utils/auth/login.js";
|
|
3
|
+
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
4
4
|
|
|
5
5
|
export function createLoginCommand(): Command {
|
|
6
6
|
return new Command("login")
|
package/src/commands/logout.ts
CHANGED
package/src/commands/whoami.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import getLoggedInUser from "
|
|
2
|
+
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
3
|
+
import { spinPromise } from "../utils/spinner.js";
|
|
3
4
|
|
|
4
5
|
export function createWhoamiCommand(): Command {
|
|
5
6
|
return new Command("whoami")
|
|
6
7
|
.description("Show current login status and user information")
|
|
7
8
|
.action(async () => {
|
|
8
9
|
try {
|
|
9
|
-
const user = await
|
|
10
|
+
const user = await spinPromise(
|
|
11
|
+
getLoggedInUser(),
|
|
12
|
+
"Checking login status...",
|
|
13
|
+
);
|
|
14
|
+
|
|
10
15
|
console.log(
|
|
11
16
|
`✅ Logged in as ${user.email} (Account ID: ${user.accountId})`,
|
|
12
17
|
);
|
package/src/utils/auth/login.ts
CHANGED
|
@@ -9,13 +9,12 @@ import {
|
|
|
9
9
|
LOGIN_PORTS,
|
|
10
10
|
LOGIN_TIMEOUT_MS,
|
|
11
11
|
ZAPIER_BASE,
|
|
12
|
-
} from "../constants";
|
|
13
|
-
import { spinPromise } from "../spinner";
|
|
14
|
-
import log from "../log";
|
|
15
|
-
import api from "../api/client";
|
|
16
|
-
import getCallablePromise from "../getCallablePromise";
|
|
17
|
-
import updateLogin from "
|
|
18
|
-
import logout from "./logout";
|
|
12
|
+
} from "../constants.js";
|
|
13
|
+
import { spinPromise } from "../spinner.js";
|
|
14
|
+
import log from "../log.js";
|
|
15
|
+
import api from "../api/client.js";
|
|
16
|
+
import getCallablePromise from "../getCallablePromise.js";
|
|
17
|
+
import { updateLogin, logout } from "@zapier/zapier-sdk";
|
|
19
18
|
|
|
20
19
|
const findAvailablePort = (): Promise<number> => {
|
|
21
20
|
return new Promise((resolve, reject) => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { ZapierSdk, hasResolver, isPositional } from "@zapier/zapier-sdk";
|
|
4
|
-
import { SchemaParameterResolver } from "./parameter-resolver";
|
|
5
|
-
import { createPager } from "./pager";
|
|
6
|
-
import { formatItemsFromSchema } from "./schema-formatter";
|
|
4
|
+
import { SchemaParameterResolver } from "./parameter-resolver.js";
|
|
5
|
+
import { createPager } from "./pager.js";
|
|
6
|
+
import { formatItemsFromSchema } from "./schema-formatter.js";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import util from "util";
|
|
9
9
|
|
package/tsconfig.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ensures we have a valid, non-expired JWT token.
|
|
3
|
-
* Will attempt to refresh expired tokens automatically.
|
|
4
|
-
* Falls back to ZAPIER_TOKEN environment variable if no stored login.
|
|
5
|
-
* Returns undefined if no token is available or refresh fails.
|
|
6
|
-
*/
|
|
7
|
-
export declare const ensureValidToken: () => Promise<string | undefined>;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import getAuthState from "./getAuthState";
|
|
2
|
-
import refreshJWT from "./refreshJWT";
|
|
3
|
-
/**
|
|
4
|
-
* Ensures we have a valid, non-expired JWT token.
|
|
5
|
-
* Will attempt to refresh expired tokens automatically.
|
|
6
|
-
* Falls back to ZAPIER_TOKEN environment variable if no stored login.
|
|
7
|
-
* Returns undefined if no token is available or refresh fails.
|
|
8
|
-
*/
|
|
9
|
-
export const ensureValidToken = async () => {
|
|
10
|
-
try {
|
|
11
|
-
const state = getAuthState();
|
|
12
|
-
if (state.status === "logged-out") {
|
|
13
|
-
// Fall back to environment variable if not logged in
|
|
14
|
-
return process.env.ZAPIER_TOKEN;
|
|
15
|
-
}
|
|
16
|
-
if (state.status === "expired") {
|
|
17
|
-
// Attempt to refresh the token
|
|
18
|
-
try {
|
|
19
|
-
return await refreshJWT();
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
// If refresh fails, fall back to environment variable
|
|
23
|
-
return process.env.ZAPIER_TOKEN;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
// Status is "logged-in", return the valid token
|
|
27
|
-
return state.jwt;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
// If any error occurs, fall back to environment variable
|
|
31
|
-
return process.env.ZAPIER_TOKEN;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { config } from "../config";
|
|
2
|
-
const getAuthState = () => {
|
|
3
|
-
const jwt = config.get("login_jwt");
|
|
4
|
-
const refreshToken = config.get("login_refresh_token");
|
|
5
|
-
const expiresAt = config.get("login_expires_at");
|
|
6
|
-
if (!jwt || !refreshToken || !expiresAt) {
|
|
7
|
-
return { status: "logged-out" };
|
|
8
|
-
}
|
|
9
|
-
if (expiresAt > Date.now() + 30 * 1000) {
|
|
10
|
-
return { status: "logged-in", jwt, refresh_token: refreshToken };
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
status: "expired",
|
|
14
|
-
refresh_token: refreshToken,
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
export default getAuthState;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import getAuthState from "./getAuthState";
|
|
2
|
-
import refreshJWT from "./refreshJWT";
|
|
3
|
-
const getJWT = async () => {
|
|
4
|
-
const state = getAuthState();
|
|
5
|
-
if (state.status === "logged-out") {
|
|
6
|
-
throw new Error("Expected getJWT to only be called when user has logged in.");
|
|
7
|
-
}
|
|
8
|
-
if (state.status === "expired") {
|
|
9
|
-
return await refreshJWT();
|
|
10
|
-
}
|
|
11
|
-
return state.jwt;
|
|
12
|
-
};
|
|
13
|
-
export default getJWT;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import jsonwebtoken from "jsonwebtoken";
|
|
2
|
-
import getJWT from "./getJWT";
|
|
3
|
-
const decodeJWTOrThrow = (jwt) => {
|
|
4
|
-
if (typeof jwt !== "string") {
|
|
5
|
-
throw new Error("Expected JWT to be a string");
|
|
6
|
-
}
|
|
7
|
-
const decodedJWT = jsonwebtoken.decode(jwt, { complete: true });
|
|
8
|
-
if (!decodedJWT) {
|
|
9
|
-
throw new Error("Could not decode JWT");
|
|
10
|
-
}
|
|
11
|
-
if (typeof decodedJWT.payload === "string") {
|
|
12
|
-
throw new Error("Did not expect JWT payload to be a string");
|
|
13
|
-
}
|
|
14
|
-
return decodedJWT;
|
|
15
|
-
};
|
|
16
|
-
const getLoggedInUser = async () => {
|
|
17
|
-
const jwt = await getJWT();
|
|
18
|
-
let decodedJwt = decodeJWTOrThrow(jwt);
|
|
19
|
-
if (decodedJwt.payload["sub_type"] == "service") {
|
|
20
|
-
decodedJwt = decodeJWTOrThrow(decodedJwt.payload["njwt"]);
|
|
21
|
-
}
|
|
22
|
-
if (typeof decodedJwt.payload["zap:acc"] !== "string") {
|
|
23
|
-
throw new Error("JWT payload does not contain accountId");
|
|
24
|
-
}
|
|
25
|
-
const accountId = parseInt(decodedJwt.payload["zap:acc"], 10);
|
|
26
|
-
if (isNaN(accountId)) {
|
|
27
|
-
throw new Error("JWT accountId is not a number");
|
|
28
|
-
}
|
|
29
|
-
if (decodedJwt.payload["sub_type"] !== "customuser" ||
|
|
30
|
-
typeof decodedJwt.payload["sub"] !== "string") {
|
|
31
|
-
throw new Error("JWT payload does not contain customUserId");
|
|
32
|
-
}
|
|
33
|
-
const customUserId = parseInt(decodedJwt.payload["sub"], 10);
|
|
34
|
-
if (isNaN(customUserId)) {
|
|
35
|
-
throw new Error("JWT customUserId is not a number");
|
|
36
|
-
}
|
|
37
|
-
const email = decodedJwt.payload["zap:uname"];
|
|
38
|
-
if (typeof email !== "string") {
|
|
39
|
-
throw new Error("JWT payload does not contain email");
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
42
|
-
accountId,
|
|
43
|
-
customUserId,
|
|
44
|
-
email,
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
export default getLoggedInUser;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, ZAPIER_BASE } from "../constants";
|
|
2
|
-
import api from "../api/client";
|
|
3
|
-
import serializeAsync from "../serializeAsync";
|
|
4
|
-
import { spinPromise } from "../spinner";
|
|
5
|
-
import getAuthState from "./getAuthState";
|
|
6
|
-
import updateLogin from "./updateLogin";
|
|
7
|
-
import logout from "./logout";
|
|
8
|
-
const refreshJWT = async () => {
|
|
9
|
-
const state = getAuthState();
|
|
10
|
-
if (state.status === "logged-out") {
|
|
11
|
-
throw new Error("Unexpected call to refreshJWT while logged out.");
|
|
12
|
-
}
|
|
13
|
-
try {
|
|
14
|
-
const { data } = await spinPromise(api.post(`${ZAPIER_BASE}/oauth/token/`, {
|
|
15
|
-
client_id: LOGIN_CLIENT_ID,
|
|
16
|
-
refresh_token: state.refresh_token,
|
|
17
|
-
grant_type: "refresh_token",
|
|
18
|
-
}, {
|
|
19
|
-
headers: {
|
|
20
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
21
|
-
[AUTH_MODE_HEADER]: "no",
|
|
22
|
-
},
|
|
23
|
-
}), "Refreshing your token...");
|
|
24
|
-
updateLogin(data);
|
|
25
|
-
return data.access_token;
|
|
26
|
-
}
|
|
27
|
-
catch (e) {
|
|
28
|
-
// Force logout
|
|
29
|
-
logout();
|
|
30
|
-
throw e;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
export default serializeAsync(refreshJWT);
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { config } from "../config";
|
|
2
|
-
const updateLogin = ({ access_token: accessToken, refresh_token: refreshToken, expires_in: expiresIn, }) => {
|
|
3
|
-
config.set("login_jwt", accessToken);
|
|
4
|
-
config.set("login_refresh_token", refreshToken);
|
|
5
|
-
config.set("login_expires_at", Date.now() + expiresIn * 1000);
|
|
6
|
-
};
|
|
7
|
-
export default updateLogin;
|
package/dist/utils/config.d.ts
DELETED
package/dist/utils/config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const getConfigPath: () => string;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import getAuthState from "./getAuthState";
|
|
2
|
-
import refreshJWT from "./refreshJWT";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Ensures we have a valid, non-expired JWT token.
|
|
6
|
-
* Will attempt to refresh expired tokens automatically.
|
|
7
|
-
* Falls back to ZAPIER_TOKEN environment variable if no stored login.
|
|
8
|
-
* Returns undefined if no token is available or refresh fails.
|
|
9
|
-
*/
|
|
10
|
-
export const ensureValidToken = async (): Promise<string | undefined> => {
|
|
11
|
-
try {
|
|
12
|
-
const state = getAuthState();
|
|
13
|
-
|
|
14
|
-
if (state.status === "logged-out") {
|
|
15
|
-
// Fall back to environment variable if not logged in
|
|
16
|
-
return process.env.ZAPIER_TOKEN;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (state.status === "expired") {
|
|
20
|
-
// Attempt to refresh the token
|
|
21
|
-
try {
|
|
22
|
-
return await refreshJWT();
|
|
23
|
-
} catch {
|
|
24
|
-
// If refresh fails, fall back to environment variable
|
|
25
|
-
return process.env.ZAPIER_TOKEN;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Status is "logged-in", return the valid token
|
|
30
|
-
return state.jwt;
|
|
31
|
-
} catch {
|
|
32
|
-
// If any error occurs, fall back to environment variable
|
|
33
|
-
return process.env.ZAPIER_TOKEN;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { config } from "../config";
|
|
2
|
-
|
|
3
|
-
type Status =
|
|
4
|
-
| {
|
|
5
|
-
status: "logged-in";
|
|
6
|
-
jwt: string;
|
|
7
|
-
refresh_token: string;
|
|
8
|
-
}
|
|
9
|
-
| {
|
|
10
|
-
status: "expired";
|
|
11
|
-
refresh_token: string;
|
|
12
|
-
}
|
|
13
|
-
| {
|
|
14
|
-
status: "logged-out";
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const getAuthState = (): Status => {
|
|
18
|
-
const jwt = config.get("login_jwt") as string | undefined;
|
|
19
|
-
const refreshToken = config.get("login_refresh_token") as string | undefined;
|
|
20
|
-
const expiresAt = config.get("login_expires_at") as number | undefined;
|
|
21
|
-
|
|
22
|
-
if (!jwt || !refreshToken || !expiresAt) {
|
|
23
|
-
return { status: "logged-out" };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (expiresAt > Date.now() + 30 * 1000) {
|
|
27
|
-
return { status: "logged-in", jwt, refresh_token: refreshToken };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
status: "expired",
|
|
32
|
-
refresh_token: refreshToken,
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export default getAuthState;
|
package/src/utils/auth/getJWT.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import getAuthState from "./getAuthState";
|
|
2
|
-
import refreshJWT from "./refreshJWT";
|
|
3
|
-
|
|
4
|
-
const getJWT = async (): Promise<string> => {
|
|
5
|
-
const state = getAuthState();
|
|
6
|
-
|
|
7
|
-
if (state.status === "logged-out") {
|
|
8
|
-
throw new Error(
|
|
9
|
-
"Expected getJWT to only be called when user has logged in.",
|
|
10
|
-
);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (state.status === "expired") {
|
|
14
|
-
return await refreshJWT();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return state.jwt;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export default getJWT;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import jsonwebtoken, { JwtPayload } from "jsonwebtoken";
|
|
2
|
-
import getJWT from "./getJWT";
|
|
3
|
-
|
|
4
|
-
const decodeJWTOrThrow = (jwt: unknown): JwtPayload => {
|
|
5
|
-
if (typeof jwt !== "string") {
|
|
6
|
-
throw new Error("Expected JWT to be a string");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const decodedJWT = jsonwebtoken.decode(jwt, { complete: true });
|
|
10
|
-
|
|
11
|
-
if (!decodedJWT) {
|
|
12
|
-
throw new Error("Could not decode JWT");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (typeof decodedJWT.payload === "string") {
|
|
16
|
-
throw new Error("Did not expect JWT payload to be a string");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return decodedJWT;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const getLoggedInUser = async (): Promise<{
|
|
23
|
-
accountId: number;
|
|
24
|
-
customUserId: number;
|
|
25
|
-
email: string;
|
|
26
|
-
}> => {
|
|
27
|
-
const jwt = await getJWT();
|
|
28
|
-
|
|
29
|
-
let decodedJwt = decodeJWTOrThrow(jwt);
|
|
30
|
-
|
|
31
|
-
if (decodedJwt.payload["sub_type"] == "service") {
|
|
32
|
-
decodedJwt = decodeJWTOrThrow(decodedJwt.payload["njwt"]);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (typeof decodedJwt.payload["zap:acc"] !== "string") {
|
|
36
|
-
throw new Error("JWT payload does not contain accountId");
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const accountId = parseInt(decodedJwt.payload["zap:acc"], 10);
|
|
40
|
-
if (isNaN(accountId)) {
|
|
41
|
-
throw new Error("JWT accountId is not a number");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
decodedJwt.payload["sub_type"] !== "customuser" ||
|
|
46
|
-
typeof decodedJwt.payload["sub"] !== "string"
|
|
47
|
-
) {
|
|
48
|
-
throw new Error("JWT payload does not contain customUserId");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const customUserId = parseInt(decodedJwt.payload["sub"], 10);
|
|
52
|
-
if (isNaN(customUserId)) {
|
|
53
|
-
throw new Error("JWT customUserId is not a number");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const email = decodedJwt.payload["zap:uname"];
|
|
57
|
-
if (typeof email !== "string") {
|
|
58
|
-
throw new Error("JWT payload does not contain email");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
accountId,
|
|
63
|
-
customUserId,
|
|
64
|
-
email,
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default getLoggedInUser;
|
package/src/utils/auth/logout.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, ZAPIER_BASE } from "../constants";
|
|
2
|
-
import api from "../api/client";
|
|
3
|
-
import serializeAsync from "../serializeAsync";
|
|
4
|
-
import { spinPromise } from "../spinner";
|
|
5
|
-
import getAuthState from "./getAuthState";
|
|
6
|
-
import updateLogin from "./updateLogin";
|
|
7
|
-
import logout from "./logout";
|
|
8
|
-
|
|
9
|
-
const refreshJWT = async (): Promise<string> => {
|
|
10
|
-
const state = getAuthState();
|
|
11
|
-
|
|
12
|
-
if (state.status === "logged-out") {
|
|
13
|
-
throw new Error("Unexpected call to refreshJWT while logged out.");
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const { data } = await spinPromise(
|
|
18
|
-
api.post<{
|
|
19
|
-
access_token: string;
|
|
20
|
-
refresh_token: string;
|
|
21
|
-
expires_in: number;
|
|
22
|
-
}>(
|
|
23
|
-
`${ZAPIER_BASE}/oauth/token/`,
|
|
24
|
-
{
|
|
25
|
-
client_id: LOGIN_CLIENT_ID,
|
|
26
|
-
refresh_token: state.refresh_token,
|
|
27
|
-
grant_type: "refresh_token",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
headers: {
|
|
31
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
32
|
-
[AUTH_MODE_HEADER]: "no",
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
),
|
|
36
|
-
"Refreshing your token...",
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
updateLogin(data);
|
|
40
|
-
|
|
41
|
-
return data.access_token;
|
|
42
|
-
} catch (e) {
|
|
43
|
-
// Force logout
|
|
44
|
-
logout();
|
|
45
|
-
|
|
46
|
-
throw e;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export default serializeAsync(refreshJWT);
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { config } from "../config";
|
|
2
|
-
|
|
3
|
-
interface LoginData {
|
|
4
|
-
access_token: string;
|
|
5
|
-
refresh_token: string;
|
|
6
|
-
expires_in: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const updateLogin = ({
|
|
10
|
-
access_token: accessToken,
|
|
11
|
-
refresh_token: refreshToken,
|
|
12
|
-
expires_in: expiresIn,
|
|
13
|
-
}: LoginData) => {
|
|
14
|
-
config.set("login_jwt", accessToken);
|
|
15
|
-
config.set("login_refresh_token", refreshToken);
|
|
16
|
-
config.set("login_expires_at", Date.now() + expiresIn * 1000);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default updateLogin;
|
package/src/utils/config.ts
DELETED