@aligndottech/cli 0.9.0 → 0.10.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/README.md +8 -5
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +13 -13
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/connector/index.d.ts.map +1 -1
- package/dist/commands/connector/index.js +2 -1
- package/dist/commands/connector/index.js.map +1 -1
- package/dist/commands/import/confluence.d.ts.map +1 -1
- package/dist/commands/import/confluence.js +28 -4
- package/dist/commands/import/confluence.js.map +1 -1
- package/dist/commands/import/github.d.ts.map +1 -1
- package/dist/commands/import/github.js +19 -3
- package/dist/commands/import/github.js.map +1 -1
- package/dist/commands/import/gitlab.d.ts.map +1 -1
- package/dist/commands/import/gitlab.js +25 -3
- package/dist/commands/import/gitlab.js.map +1 -1
- package/dist/commands/import/jira.d.ts.map +1 -1
- package/dist/commands/import/jira.js +27 -5
- package/dist/commands/import/jira.js.map +1 -1
- package/dist/commands/import/linear.d.ts.map +1 -1
- package/dist/commands/import/linear.js +18 -2
- package/dist/commands/import/linear.js.map +1 -1
- package/dist/commands/import/notion.d.ts.map +1 -1
- package/dist/commands/import/notion.js +18 -2
- package/dist/commands/import/notion.js.map +1 -1
- package/dist/commands/import/slack.d.ts.map +1 -1
- package/dist/commands/import/slack.js +18 -2
- package/dist/commands/import/slack.js.map +1 -1
- package/dist/commands/import/teams.d.ts.map +1 -1
- package/dist/commands/import/teams.js +18 -2
- package/dist/commands/import/teams.js.map +1 -1
- package/dist/commands/import/zoom.d.ts.map +1 -1
- package/dist/commands/import/zoom.js +18 -2
- package/dist/commands/import/zoom.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +3 -1
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +1 -118
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +17 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/lib/personal-oauth.d.ts +41 -0
- package/dist/lib/personal-oauth.d.ts.map +1 -0
- package/dist/lib/personal-oauth.js +169 -0
- package/dist/lib/personal-oauth.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { createConfigStore, EnvName } from './config.js';
|
|
2
|
+
import type { createGatewayClient } from './gateway-client.js';
|
|
3
|
+
type ConfigStore = ReturnType<typeof createConfigStore>;
|
|
4
|
+
type GatewayClient = ReturnType<typeof createGatewayClient>;
|
|
5
|
+
/** The subset of a setup source the OAuth flow needs; setup's SetupSource is assignable. */
|
|
6
|
+
export interface OAuthSource {
|
|
7
|
+
oauthKey?: string;
|
|
8
|
+
label: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function isAtlassianOAuth(source: OAuthSource): boolean;
|
|
11
|
+
export declare function oauthFlowLabel(source: OAuthSource): string;
|
|
12
|
+
export declare function collectTokensViaOAuth(source: OAuthSource, client: GatewayClient, config: ConfigStore, envName: EnvName, reset?: boolean, connectedThisRun?: Set<string>): Promise<Record<string, string> | null>;
|
|
13
|
+
export declare function persistConnectorCreds(config: ConfigStore, envName: EnvName, key: string, credentials: Record<string, unknown>): void;
|
|
14
|
+
/**
|
|
15
|
+
* Import source id -> the gateway OAuth key for a personal (non-admin) connection.
|
|
16
|
+
* Every key here must exist in the gateway's getOAuthConfig switch. Teams and Zoom have
|
|
17
|
+
* no separate personal app; the CLI flow uses the org key and the gateway's CLI branch
|
|
18
|
+
* keeps the credentials local either way.
|
|
19
|
+
*/
|
|
20
|
+
export declare const PERSONAL_OAUTH_KEYS: Record<string, string>;
|
|
21
|
+
export interface PersonalCreds {
|
|
22
|
+
token: string;
|
|
23
|
+
cloudId?: string;
|
|
24
|
+
siteBase?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve credentials for `align import <src> --personal`: the cached personal OAuth token
|
|
28
|
+
* when one exists, otherwise the browser flow. Throws with a user-readable message when the
|
|
29
|
+
* flow cannot run here - callers print it and exit rather than opening a doomed browser.
|
|
30
|
+
*/
|
|
31
|
+
export declare function personalCredsForImport(sourceId: string, label: string, deps: {
|
|
32
|
+
config: ConfigStore;
|
|
33
|
+
envName: EnvName;
|
|
34
|
+
env: {
|
|
35
|
+
mode?: string;
|
|
36
|
+
authToken?: string | null;
|
|
37
|
+
};
|
|
38
|
+
client: GatewayClient;
|
|
39
|
+
}): Promise<PersonalCreds>;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=personal-oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personal-oauth.d.ts","sourceRoot":"","sources":["../../src/lib/personal-oauth.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG/D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACxD,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAE5D,4FAA4F;AAC5F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAE7D;AACD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE1D;AAOD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,OAAO,EAChB,KAAK,UAAQ,EACb,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CA0FxC;AAID,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAQN;AAMD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUtD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IACJ,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAClD,MAAM,EAAE,aAAa,CAAC;CACvB,GACA,OAAO,CAAC,aAAa,CAAC,CAuBxB"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// The Align Personal OAuth flow, shared by `align setup` and `align import <src> --personal`
|
|
2
|
+
// (ALI-388). Lifted verbatim from setup.ts so both entry points use one implementation: the
|
|
3
|
+
// gateway's /oauth/cli-start/:key begins the flow, the browser lands credentials on the
|
|
4
|
+
// localhost listener (cli-oauth.ts), and tokens persist in the local config under the
|
|
5
|
+
// connector's oauth key - the gateway's CLI branch never writes them server-side.
|
|
6
|
+
import * as p from '@clack/prompts';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import open from 'open';
|
|
9
|
+
import { CLI_CALLBACK_PORTS, waitForCallback } from './cli-oauth.js';
|
|
10
|
+
// Jira and Confluence share one Atlassian OAuth app: one consent connects both, so a
|
|
11
|
+
// user connecting "Jira" isn't surprised that Confluence is connected too.
|
|
12
|
+
const ATLASSIAN_OAUTH_KEYS = new Set(['jira-personal', 'confluence-personal']);
|
|
13
|
+
export function isAtlassianOAuth(source) {
|
|
14
|
+
return !!source.oauthKey && ATLASSIAN_OAUTH_KEYS.has(source.oauthKey);
|
|
15
|
+
}
|
|
16
|
+
export function oauthFlowLabel(source) {
|
|
17
|
+
return isAtlassianOAuth(source) ? 'Atlassian (Jira & Confluence)' : source.label;
|
|
18
|
+
}
|
|
19
|
+
function connectorDisplayName(connectorKey) {
|
|
20
|
+
if (connectorKey.startsWith('confluence'))
|
|
21
|
+
return 'Confluence';
|
|
22
|
+
if (connectorKey.startsWith('jira'))
|
|
23
|
+
return 'Jira';
|
|
24
|
+
return connectorKey;
|
|
25
|
+
}
|
|
26
|
+
export async function collectTokensViaOAuth(source, client, config, envName, reset = false, connectedThisRun) {
|
|
27
|
+
const key = source.oauthKey;
|
|
28
|
+
const readCachedTokens = () => {
|
|
29
|
+
const cached = config.getConnectorToken(envName, key);
|
|
30
|
+
if (!cached)
|
|
31
|
+
return null;
|
|
32
|
+
const cachedCloudId = config.getConnectorCloudId(envName, key);
|
|
33
|
+
const cachedSiteBase = config.getConnectorSiteBase(envName, key);
|
|
34
|
+
return {
|
|
35
|
+
token: cached,
|
|
36
|
+
...(cachedCloudId ? { cloudId: cachedCloudId } : {}),
|
|
37
|
+
...(cachedSiteBase ? { siteBase: cachedSiteBase } : {}),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
// Connected earlier in THIS run (the Atlassian sibling: Jira and Confluence
|
|
41
|
+
// share one OAuth app + token, so one consent connects both). Reuse it even
|
|
42
|
+
// under --reset, which is meant to ignore STALE tokens from prior runs, not
|
|
43
|
+
// ones just obtained moments ago this run.
|
|
44
|
+
if (connectedThisRun?.has(key)) {
|
|
45
|
+
const reused = readCachedTokens();
|
|
46
|
+
if (reused) {
|
|
47
|
+
p.log.info(chalk.dim(` ${source.label}: already connected via a shared sign-in this run`));
|
|
48
|
+
return reused;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!reset) {
|
|
52
|
+
const cached = readCachedTokens();
|
|
53
|
+
if (cached) {
|
|
54
|
+
p.log.info(chalk.dim(` ${source.label}: using cached OAuth token (run align setup --reset to re-auth)`));
|
|
55
|
+
return cached;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const spinner = p.spinner();
|
|
59
|
+
spinner.start(`Opening browser for ${oauthFlowLabel(source)} OAuth...`);
|
|
60
|
+
let authUrl = '';
|
|
61
|
+
const callbackPromise = waitForCallback({
|
|
62
|
+
ports: CLI_CALLBACK_PORTS,
|
|
63
|
+
timeoutMs: 120_000,
|
|
64
|
+
onBound: async (port, nonce) => {
|
|
65
|
+
try {
|
|
66
|
+
const result = await client.startCliOAuth(key, port, nonce);
|
|
67
|
+
authUrl = result.authUrl;
|
|
68
|
+
await open(authUrl).catch(() => { });
|
|
69
|
+
spinner.stop(`Browser opened for ${oauthFlowLabel(source)}. If nothing happened, visit:\n ${chalk.bold(authUrl)}`);
|
|
70
|
+
p.log.info('Waiting for you to approve in the browser (2 min timeout)...');
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
spinner.stop(`Could not start OAuth for ${source.label}: ${e.message}`);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
let result;
|
|
78
|
+
try {
|
|
79
|
+
result = await callbackPromise;
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
p.log.warn(`${source.label} OAuth timed out or failed: ${e.message}`);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const credentials = result.data['credentials'];
|
|
86
|
+
const accessToken = credentials?.['access_token'];
|
|
87
|
+
if (!accessToken) {
|
|
88
|
+
p.log.warn(`${source.label} OAuth did not return an access token.`);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
// accessToken being truthy guarantees credentials is defined
|
|
92
|
+
persistConnectorCreds(config, envName, key, credentials);
|
|
93
|
+
connectedThisRun?.add(key);
|
|
94
|
+
// Atlassian: Jira and Confluence share one OAuth app, so a single consent
|
|
95
|
+
// returns the sibling's credentials too. Persist them AND mark the sibling
|
|
96
|
+
// connected this run so its own iteration reuses the token and skips a second
|
|
97
|
+
// browser flow (even under --reset).
|
|
98
|
+
const siblingConnector = result.data['siblingConnector'];
|
|
99
|
+
const siblingCreds = result.data['siblingCredentials'];
|
|
100
|
+
if (siblingConnector && siblingCreds?.['access_token']) {
|
|
101
|
+
persistConnectorCreds(config, envName, siblingConnector, siblingCreds);
|
|
102
|
+
connectedThisRun?.add(siblingConnector);
|
|
103
|
+
p.log.info(chalk.dim(` Also connected ${connectorDisplayName(siblingConnector)} (shared Atlassian app - no second sign-in needed)`));
|
|
104
|
+
}
|
|
105
|
+
const cloudId = credentials?.['site_id'];
|
|
106
|
+
const siteBase = credentials?.['base'];
|
|
107
|
+
return { token: accessToken, ...(cloudId ? { cloudId } : {}), ...(siteBase ? { siteBase } : {}) };
|
|
108
|
+
}
|
|
109
|
+
// Persist a connector's OAuth token plus Atlassian cloudId/site base so future
|
|
110
|
+
// runs (and `align import`) can reuse the credentials without re-auth.
|
|
111
|
+
export function persistConnectorCreds(config, envName, key, credentials) {
|
|
112
|
+
const accessToken = credentials['access_token'];
|
|
113
|
+
if (!accessToken)
|
|
114
|
+
return;
|
|
115
|
+
config.setConnectorToken(envName, key, accessToken);
|
|
116
|
+
const cloudId = credentials['site_id'];
|
|
117
|
+
if (cloudId)
|
|
118
|
+
config.setConnectorCloudId(envName, key, cloudId);
|
|
119
|
+
const siteBase = credentials['base'];
|
|
120
|
+
if (siteBase)
|
|
121
|
+
config.setConnectorSiteBase(envName, key, siteBase);
|
|
122
|
+
}
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// `align import <src> --personal` (ALI-388)
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
/**
|
|
127
|
+
* Import source id -> the gateway OAuth key for a personal (non-admin) connection.
|
|
128
|
+
* Every key here must exist in the gateway's getOAuthConfig switch. Teams and Zoom have
|
|
129
|
+
* no separate personal app; the CLI flow uses the org key and the gateway's CLI branch
|
|
130
|
+
* keeps the credentials local either way.
|
|
131
|
+
*/
|
|
132
|
+
export const PERSONAL_OAUTH_KEYS = {
|
|
133
|
+
github: 'github-personal',
|
|
134
|
+
gitlab: 'gitlab-personal',
|
|
135
|
+
linear: 'linear-personal',
|
|
136
|
+
notion: 'notion-personal',
|
|
137
|
+
slack: 'slack-personal',
|
|
138
|
+
jira: 'jira-personal',
|
|
139
|
+
confluence: 'confluence-personal',
|
|
140
|
+
teams: 'teams',
|
|
141
|
+
zoom: 'zoom',
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Resolve credentials for `align import <src> --personal`: the cached personal OAuth token
|
|
145
|
+
* when one exists, otherwise the browser flow. Throws with a user-readable message when the
|
|
146
|
+
* flow cannot run here - callers print it and exit rather than opening a doomed browser.
|
|
147
|
+
*/
|
|
148
|
+
export async function personalCredsForImport(sourceId, label, deps) {
|
|
149
|
+
const oauthKey = PERSONAL_OAUTH_KEYS[sourceId];
|
|
150
|
+
if (!oauthKey) {
|
|
151
|
+
throw new Error(`--personal is not supported for ${sourceId}. Pass --token instead.`);
|
|
152
|
+
}
|
|
153
|
+
if (deps.env.mode === 'local-embedded') {
|
|
154
|
+
throw new Error('--personal needs a cloud environment: the OAuth flow starts at the Align gateway. Run `align login` and retry with --env prod (or preview), or keep using --token.');
|
|
155
|
+
}
|
|
156
|
+
if (!deps.env.authToken) {
|
|
157
|
+
throw new Error('--personal requires an Align login first: run `align login`, then retry.');
|
|
158
|
+
}
|
|
159
|
+
const tokens = await collectTokensViaOAuth({ oauthKey, label }, deps.client, deps.config, deps.envName);
|
|
160
|
+
if (!tokens?.token) {
|
|
161
|
+
throw new Error(`${label} OAuth did not complete. Retry, or pass --token instead.`);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
token: tokens.token,
|
|
165
|
+
...(tokens.cloudId ? { cloudId: tokens.cloudId } : {}),
|
|
166
|
+
...(tokens.siteBase ? { siteBase: tokens.siteBase } : {}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=personal-oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personal-oauth.js","sourceRoot":"","sources":["../../src/lib/personal-oauth.ts"],"names":[],"mappings":"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"}
|