@lightdash/cli 3.86.0 → 3.88.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 +18 -0
- package/dist/.tsbuildinfo.build +1 -1
- package/dist/agentConnections/agentTokenProvider.d.ts.map +1 -1
- package/dist/agentConnections/agentTokenProvider.js +9 -5
- package/dist/agentConnections/commandPolicy.d.ts.map +1 -1
- package/dist/agentConnections/commandPolicy.js +1 -0
- package/dist/agentConnections/initialToken.d.ts.map +1 -1
- package/dist/agentConnections/initialToken.js +2 -0
- package/dist/agentConnections/personalRecovery.js +1 -1
- package/dist/analytics/analytics.js +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -11
- package/dist/credentials.d.ts +5 -0
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +11 -2
- package/dist/handlers/apps/createApp.d.ts.map +1 -1
- package/dist/handlers/apps/createApp.js +1 -3
- package/dist/handlers/apps/preview.d.ts.map +1 -1
- package/dist/handlers/apps/preview.js +12 -10
- package/dist/handlers/apps/previewProxy.d.ts +1 -0
- package/dist/handlers/apps/previewProxy.d.ts.map +1 -1
- package/dist/handlers/apps/previewProxy.js +70 -44
- package/dist/handlers/dbt/apiClient.d.ts.map +1 -1
- package/dist/handlers/dbt/apiClient.js +20 -12
- package/dist/handlers/diagnostics.d.ts.map +1 -1
- package/dist/handlers/diagnostics.js +2 -1
- package/dist/handlers/download.d.ts.map +1 -1
- package/dist/handlers/download.js +4 -9
- package/dist/handlers/login/pat.d.ts.map +1 -1
- package/dist/handlers/login/pat.js +2 -0
- package/dist/handlers/login.d.ts.map +1 -1
- package/dist/handlers/login.js +8 -2
- package/dist/handlers/logout.d.ts +3 -0
- package/dist/handlers/logout.d.ts.map +1 -0
- package/dist/handlers/logout.js +67 -0
- package/dist/handlers/oauthLogin.d.ts +1 -1
- package/dist/handlers/oauthLogin.d.ts.map +1 -1
- package/dist/handlers/oauthLogin.js +64 -31
- package/dist/handlers/renameHandler.d.ts.map +1 -1
- package/dist/handlers/renameHandler.js +3 -3
- package/dist/handlers/slugUpdate.d.ts.map +1 -1
- package/dist/handlers/slugUpdate.js +3 -3
- package/dist/handlers/utils.d.ts.map +1 -1
- package/dist/handlers/utils.js +1 -0
- package/dist/index.js +6 -0
- package/dist/personalLogin/fixtures.d.ts +3 -0
- package/dist/personalLogin/fixtures.d.ts.map +1 -0
- package/dist/personalLogin/fixtures.js +20 -0
- package/dist/personalLogin/instanceKey.d.ts +2 -0
- package/dist/personalLogin/instanceKey.d.ts.map +1 -0
- package/dist/personalLogin/instanceKey.js +23 -0
- package/dist/personalLogin/schema.d.ts +28 -0
- package/dist/personalLogin/schema.d.ts.map +1 -0
- package/dist/personalLogin/schema.js +69 -0
- package/dist/personalLogin/store.d.ts +24 -0
- package/dist/personalLogin/store.d.ts.map +1 -0
- package/dist/personalLogin/store.js +124 -0
- package/dist/personalLogin/tokenProvider.d.ts +31 -0
- package/dist/personalLogin/tokenProvider.d.ts.map +1 -0
- package/dist/personalLogin/tokenProvider.js +180 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentTokenProvider.d.ts","sourceRoot":"","sources":["../../src/agentConnections/agentTokenProvider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agentTokenProvider.d.ts","sourceRoot":"","sources":["../../src/agentConnections/agentTokenProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,KAAK,mBAAmB,EAAE,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAEhF,OAAO,EAAE,oBAAoB,EAAoB,MAAM,SAAS,CAAC;AAyDjE,eAAO,MAAM,gBAAgB,SACnB,mBAAmB,OACpB,MAAM,KACZ,IAsCF,CAAC;AAEF,qBAAa,kBAAkB;IAIvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAH1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAE9C,YACqB,KAAK,GAAE,oBAAiD,EACzE;YAEU,MAAM;YA+DN,SAAS;IAkBjB,QAAQ,CACV,GAAG,EAAE,OAAO,EACZ,kBAAkB,GAAE,MAAM,GAAG,IAAW,EACxC,kBAAkB,GAAE,MAAM,GAAG,IAAW,GACzC,OAAO,CAAC,mBAAmB,CAAC,CAwL9B;IACK,iBAAiB,CACnB,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,OAAO,aAAa,EAAE,kBAAkB,EACnD,kBAAkB,EAAE,MAAM,GAAG,IAAI,EACjC,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAClC,OAAO,CAAC,mBAAmB,CAAC,CA0B9B;CACJ"}
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const common_1 = require("@lightdash/common");
|
|
6
6
|
const ajv_1 = tslib_1.__importDefault(require("ajv"));
|
|
7
7
|
const crypto_1 = require("crypto");
|
|
8
|
+
const env_1 = require("../env");
|
|
8
9
|
const apiUrl_1 = require("./apiUrl");
|
|
9
10
|
const schema_1 = require("./schema");
|
|
10
11
|
const statusResponse_1 = require("./statusResponse");
|
|
@@ -205,11 +206,14 @@ class AgentTokenProvider {
|
|
|
205
206
|
body,
|
|
206
207
|
redirect: 'error',
|
|
207
208
|
signal: AbortSignal.timeout(15_000),
|
|
208
|
-
headers:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
headers: {
|
|
210
|
+
'User-Agent': `lightdash-cli/${env_1.CLI_VERSION}`,
|
|
211
|
+
...(proxyAuthorization === null
|
|
212
|
+
? {}
|
|
213
|
+
: {
|
|
214
|
+
'Proxy-Authorization': proxyAuthorization,
|
|
215
|
+
}),
|
|
216
|
+
},
|
|
213
217
|
});
|
|
214
218
|
if (!response.ok)
|
|
215
219
|
throw reconnectError();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandPolicy.d.ts","sourceRoot":"","sources":["../../src/agentConnections/commandPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,KAAK,aAAa,GACZ;IAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,WAAW,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAcjE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"commandPolicy.d.ts","sourceRoot":"","sources":["../../src/agentConnections/commandPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,KAAK,aAAa,GACZ;IAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,WAAW,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAcjE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CA8DlE,CAAC;AAqBF,eAAO,MAAM,yBAAyB,SAC5B,MAAM,YACH,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC3C,IA6BF,CAAC;AAEF,eAAO,MAAM,gBAAgB,YAAa,OAAO,KAAG,MASnD,CAAC"}
|
|
@@ -15,6 +15,7 @@ exports.COMMAND_POLICY = {
|
|
|
15
15
|
'upgrade-check': local('Public release index only'),
|
|
16
16
|
'connect-snowflake': refuse('Separate warehouse credential deposit'),
|
|
17
17
|
login: refuse('Personal bootstrap', credentials_1.personalLoginRequired),
|
|
18
|
+
logout: refuse('Personal session logout', credentials_1.personalLoginRequired),
|
|
18
19
|
agent: local('Command group'),
|
|
19
20
|
'agent connect': refuse('Personal bootstrap', credentials_1.personalLoginRequired),
|
|
20
21
|
'agent status': admit('Own connection status'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialToken.d.ts","sourceRoot":"","sources":["../../src/agentConnections/initialToken.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"initialToken.d.ts","sourceRoot":"","sources":["../../src/agentConnections/initialToken.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iBAAiB,qGACwE,CAAC;AACvG,qBAAa,oBAAqB,SAAQ,KAAK;IAC3C,YAAY,OAAO,SAAoB,EAEtC;CACJ;AACD,eAAO,MAAM,8BAA8B,yFAQxC;IACC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;;;;;QA4EW,WAAW;QACX,YAAY;QACZ,oBAAoB;QAGpB,qBAAqB;QAGrB,MAAM;QACN,UAAU;QACV,sBAAsB;;EAGjC,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.exchangeInitialConnectionToken = exports.ConnectionProofError = exports.unboundConnection = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
|
+
const env_1 = require("../env");
|
|
5
6
|
const apiUrl_1 = require("./apiUrl");
|
|
6
7
|
const approvedProjectProof_1 = require("./approvedProjectProof");
|
|
7
8
|
const statusResponse_1 = require("./statusResponse");
|
|
@@ -19,6 +20,7 @@ const exchangeInitialConnectionToken = async ({ instanceUrl, code, verifier, red
|
|
|
19
20
|
method: 'POST',
|
|
20
21
|
headers: {
|
|
21
22
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
23
|
+
'User-Agent': `lightdash-cli/${env_1.CLI_VERSION}`,
|
|
22
24
|
...(proxyAuthorization === null
|
|
23
25
|
? {}
|
|
24
26
|
: { 'Proxy-Authorization': proxyAuthorization }),
|
|
@@ -11,7 +11,7 @@ const statusResponse_1 = require("./statusResponse");
|
|
|
11
11
|
class PersonalRecoveryError extends Error {
|
|
12
12
|
constructor(mode = 'recovery') {
|
|
13
13
|
super(mode === 'bootstrap'
|
|
14
|
-
? 'Agent connection approval
|
|
14
|
+
? 'Agent connection approval needs a personal access token login. Run `lightdash login <url> --token <personal access token>` and retry. Browser logins and service account credentials cannot start approval.'
|
|
15
15
|
: 'The personal CLI login does not match this connection person and organisation.');
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -30,7 +30,7 @@ const detectCI = () => {
|
|
|
30
30
|
const identifyUser = async () => {
|
|
31
31
|
(0, credentials_1.refuseAgentConnection)();
|
|
32
32
|
const config = await (0, config_1.getConfig)();
|
|
33
|
-
if (config.context?.serverUrl
|
|
33
|
+
if (config.context?.serverUrl) {
|
|
34
34
|
try {
|
|
35
35
|
const user = await (0, apiClient_1.lightdashApi)({
|
|
36
36
|
method: 'GET',
|
package/dist/config.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export type Config = {
|
|
|
28
28
|
export declare const ensureConfigFilePermissions: (filePath: string) => Promise<void>;
|
|
29
29
|
/** @internal Exported for filesystem-permission regression tests. */
|
|
30
30
|
export declare const writeConfigToFile: (filePath: string, config: Config) => Promise<void>;
|
|
31
|
+
export declare const getRawConfig: () => Promise<Config>;
|
|
31
32
|
export declare const getConfig: ({ readOnly, }?: {
|
|
32
33
|
readOnly?: boolean;
|
|
33
34
|
}) => Promise<Config>;
|
|
@@ -39,4 +40,5 @@ export declare const unsetPreviewProject: () => Promise<void>;
|
|
|
39
40
|
export declare const setDefaultUser: (userUuid: string, organizationUuid: string) => Promise<void>;
|
|
40
41
|
export declare const setContext: (context: Config['context']) => Promise<void>;
|
|
41
42
|
export declare const setAnswer: (answer: Config['answers']) => Promise<void>;
|
|
43
|
+
export declare const unsetApiKey: () => Promise<void>;
|
|
42
44
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,QAAsC,CAAC;AAElE,MAAM,MAAM,MAAM,GAAG;IACjB,IAAI,CAAC,EAAE;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;;WAGG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,OAAO,CAAC,EAAE;QACN,qCAAqC,CAAC,EAAE,OAAO,CAAC;QAChD,gCAAgC,CAAC,EAAE,OAAO,CAAC;KAC9C,CAAC;CACL,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,aAC1B,MAAM,KACjB,OAAO,CAAC,IAAI,CAgBd,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,aAChB,MAAM,UACR,MAAM,KACf,OAAO,CAAC,IAAI,CAed,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,QAAsC,CAAC;AAElE,MAAM,MAAM,MAAM,GAAG;IACjB,IAAI,CAAC,EAAE;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;;WAGG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,OAAO,CAAC,EAAE;QACN,qCAAqC,CAAC,EAAE,OAAO,CAAC;QAChD,gCAAgC,CAAC,EAAE,OAAO,CAAC;KAC9C,CAAC;CACL,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,aAC1B,MAAM,KACjB,OAAO,CAAC,IAAI,CAgBd,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,aAChB,MAAM,UACR,MAAM,KACf,OAAO,CAAC,IAAI,CAed,CAAC;AAMF,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,MAAM,CAgBnD,CAAC;AAeF,eAAO,MAAM,SAAS,mBAEnB;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAAQ,OAAO,CAAC,MAAM,CA6B9C,CAAC;AAEF,eAAO,MAAM,UAAU,gBAAuB,MAAM,eAAe,MAAM,kBAcxE,CAAC;AAEF,eAAO,MAAM,YAAY,qBAWxB,CAAC;AAEF,eAAO,MAAM,SAAS,WAAkB,MAAM,kBAS7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,gBAAuB,MAAM,QAAQ,MAAM,kBAUxE,CAAC;AAEF,eAAO,MAAM,mBAAmB,qBAU/B,CAAC;AAEF,eAAO,MAAM,cAAc,aACb,MAAM,oBACE,MAAM,kBAW3B,CAAC;AAEF,eAAO,MAAM,UAAU,YAAmB,MAAM,CAAC,SAAS,CAAC,kBAM1D,CAAC;AAEF,eAAO,MAAM,SAAS,WAAkB,MAAM,CAAC,SAAS,CAAC,kBAMxD,CAAC;AAEF,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,IAAI,CAIhD,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setAnswer = exports.setContext = exports.setDefaultUser = exports.unsetPreviewProject = exports.setPreviewProject = exports.setSource = exports.unsetProject = exports.setProject = exports.getConfig = exports.writeConfigToFile = exports.ensureConfigFilePermissions = exports.configFilePath = void 0;
|
|
3
|
+
exports.unsetApiKey = exports.setAnswer = exports.setContext = exports.setDefaultUser = exports.unsetPreviewProject = exports.setPreviewProject = exports.setSource = exports.unsetProject = exports.setProject = exports.getConfig = exports.getRawConfig = exports.writeConfigToFile = exports.ensureConfigFilePermissions = exports.configFilePath = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const yaml = tslib_1.__importStar(require("js-yaml"));
|
|
@@ -63,8 +63,9 @@ const getRawConfig = async () => {
|
|
|
63
63
|
throw e;
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
|
+
exports.getRawConfig = getRawConfig;
|
|
66
67
|
const setAnonymousUuid = async (anonymousUuid) => {
|
|
67
|
-
const config = await getRawConfig();
|
|
68
|
+
const config = await (0, exports.getRawConfig)();
|
|
68
69
|
const newConfig = {
|
|
69
70
|
...config,
|
|
70
71
|
user: {
|
|
@@ -76,7 +77,7 @@ const setAnonymousUuid = async (anonymousUuid) => {
|
|
|
76
77
|
return newConfig;
|
|
77
78
|
};
|
|
78
79
|
const getConfig = async ({ readOnly = false, } = {}) => {
|
|
79
|
-
let rawConfig = await getRawConfig();
|
|
80
|
+
let rawConfig = await (0, exports.getRawConfig)();
|
|
80
81
|
if (!readOnly && rawConfig.user?.anonymousUuid === undefined) {
|
|
81
82
|
rawConfig = await setAnonymousUuid((0, uuid_1.v4)());
|
|
82
83
|
}
|
|
@@ -102,7 +103,7 @@ const getConfig = async ({ readOnly = false, } = {}) => {
|
|
|
102
103
|
};
|
|
103
104
|
exports.getConfig = getConfig;
|
|
104
105
|
const setProject = async (projectUuid, projectName) => {
|
|
105
|
-
const config = await getRawConfig();
|
|
106
|
+
const config = await (0, exports.getRawConfig)();
|
|
106
107
|
await setConfig({
|
|
107
108
|
...config,
|
|
108
109
|
context: {
|
|
@@ -117,7 +118,7 @@ const setProject = async (projectUuid, projectName) => {
|
|
|
117
118
|
};
|
|
118
119
|
exports.setProject = setProject;
|
|
119
120
|
const unsetProject = async () => {
|
|
120
|
-
const config = await getRawConfig();
|
|
121
|
+
const config = await (0, exports.getRawConfig)();
|
|
121
122
|
await setConfig({
|
|
122
123
|
...config,
|
|
123
124
|
context: {
|
|
@@ -130,7 +131,7 @@ const unsetProject = async () => {
|
|
|
130
131
|
};
|
|
131
132
|
exports.unsetProject = unsetProject;
|
|
132
133
|
const setSource = async (source) => {
|
|
133
|
-
const config = await getRawConfig();
|
|
134
|
+
const config = await (0, exports.getRawConfig)();
|
|
134
135
|
await setConfig({
|
|
135
136
|
...config,
|
|
136
137
|
context: {
|
|
@@ -141,7 +142,7 @@ const setSource = async (source) => {
|
|
|
141
142
|
};
|
|
142
143
|
exports.setSource = setSource;
|
|
143
144
|
const setPreviewProject = async (projectUuid, name) => {
|
|
144
|
-
const config = await getRawConfig();
|
|
145
|
+
const config = await (0, exports.getRawConfig)();
|
|
145
146
|
await setConfig({
|
|
146
147
|
...config,
|
|
147
148
|
context: {
|
|
@@ -153,7 +154,7 @@ const setPreviewProject = async (projectUuid, name) => {
|
|
|
153
154
|
};
|
|
154
155
|
exports.setPreviewProject = setPreviewProject;
|
|
155
156
|
const unsetPreviewProject = async () => {
|
|
156
|
-
const config = await getRawConfig();
|
|
157
|
+
const config = await (0, exports.getRawConfig)();
|
|
157
158
|
await setConfig({
|
|
158
159
|
...config,
|
|
159
160
|
context: {
|
|
@@ -165,7 +166,7 @@ const unsetPreviewProject = async () => {
|
|
|
165
166
|
};
|
|
166
167
|
exports.unsetPreviewProject = unsetPreviewProject;
|
|
167
168
|
const setDefaultUser = async (userUuid, organizationUuid) => {
|
|
168
|
-
const config = await getRawConfig();
|
|
169
|
+
const config = await (0, exports.getRawConfig)();
|
|
169
170
|
await setConfig({
|
|
170
171
|
...config,
|
|
171
172
|
user: {
|
|
@@ -177,7 +178,7 @@ const setDefaultUser = async (userUuid, organizationUuid) => {
|
|
|
177
178
|
};
|
|
178
179
|
exports.setDefaultUser = setDefaultUser;
|
|
179
180
|
const setContext = async (context) => {
|
|
180
|
-
const config = await getRawConfig();
|
|
181
|
+
const config = await (0, exports.getRawConfig)();
|
|
181
182
|
await setConfig({
|
|
182
183
|
...config,
|
|
183
184
|
context,
|
|
@@ -185,10 +186,17 @@ const setContext = async (context) => {
|
|
|
185
186
|
};
|
|
186
187
|
exports.setContext = setContext;
|
|
187
188
|
const setAnswer = async (answer) => {
|
|
188
|
-
const config = await getRawConfig();
|
|
189
|
+
const config = await (0, exports.getRawConfig)();
|
|
189
190
|
await setConfig({
|
|
190
191
|
...config,
|
|
191
192
|
answers: lodash_1.default.merge(config.answers, answer),
|
|
192
193
|
});
|
|
193
194
|
};
|
|
194
195
|
exports.setAnswer = setAnswer;
|
|
196
|
+
const unsetApiKey = async () => {
|
|
197
|
+
const config = await (0, exports.getRawConfig)();
|
|
198
|
+
if (config.context)
|
|
199
|
+
delete config.context.apiKey;
|
|
200
|
+
await setConfig(config);
|
|
201
|
+
};
|
|
202
|
+
exports.unsetApiKey = unsetApiKey;
|
package/dist/credentials.d.ts
CHANGED
|
@@ -2,12 +2,17 @@ import { type AgentTokenProvider } from './agentConnections/agentTokenProvider';
|
|
|
2
2
|
import { type LifecycleOperation } from './agentConnections/lifecycle';
|
|
3
3
|
import { type AgentConnectionSlot } from './agentConnections/schema';
|
|
4
4
|
import { type Config } from './config';
|
|
5
|
+
import { type PersonalLogin } from './personalLogin/schema';
|
|
5
6
|
export type Credential = {
|
|
6
7
|
kind: 'human_api_key';
|
|
7
8
|
token: string;
|
|
8
9
|
} | {
|
|
9
10
|
kind: 'service_account';
|
|
10
11
|
token: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'personal_oauth';
|
|
14
|
+
token: string;
|
|
15
|
+
login: PersonalLogin;
|
|
11
16
|
} | {
|
|
12
17
|
kind: 'agent_connection';
|
|
13
18
|
token: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAO7E,eAAO,MAAM,wBAAwB,QAAO,IAK3C,CAAC;AAMF,eAAO,MAAM,gCAAgC,cAC9B,MAAM,GAAG,IAAI,KACzB,MAAM,GAAG,IASX,CAAC;AACF,eAAO,MAAM,qCAAqC,GAAI,CAAC,iBACpC,MAAM,MAAM,GAAG,IAAI,iBACnB,OAAO,UACd,MAAM,CAAC,KAChB,CAoDF,CAAC;AACF,eAAO,MAAM,2BAA2B,QAAO,MAAM,GAAG,IAQvD,CAAC;AACF,eAAO,MAAM,+BAA+B,GAAI,CAAC,aAClC,MAAM,GAAG,IAAI,UAChB,MAAM,CAAC,KAChB,CAQE,CAAC;AACN,eAAO,MAAM,eAAe,UAAW,MAAM,KAAG,UAK9C,CAAC;AACH,eAAO,MAAM,iBAAiB,WAClB,MAAM,aACJ,kBAAkB,GAAG,IAAI,uBACf,MAAM,GAAG,IAAI,cACtB,kBAAkB,GAAG,IAAI,KACrC,OAAO,CAAC,UAAU,CAqEpB,CAAC;AACF,eAAO,MAAM,qBAAqB,mHACkF,CAAC;AACrH,eAAO,MAAM,uBAAuB,+JAC4H,CAAC;AACjK,eAAO,MAAM,qBAAqB,8BAA2B,IAK5D,CAAC;AAEF,eAAO,MAAM,kCAAkC,eAChC,MAAM,CAAC,UAAU,KAC7B,OAAO,CAAC,MAAM,CAAC,UAAU,CAqB3B,CAAC"}
|
package/dist/credentials.js
CHANGED
|
@@ -101,9 +101,18 @@ const resolveCredential = async (config, provider = null, rejectedGeneration = n
|
|
|
101
101
|
if (name === null) {
|
|
102
102
|
if (lifecycle !== null)
|
|
103
103
|
throw new Error('An agent connection selection is required.');
|
|
104
|
-
if (!
|
|
104
|
+
if (!config.context?.serverUrl)
|
|
105
105
|
throw new common_1.AuthorizationError(`Not logged in. Run 'lightdash login --help'`);
|
|
106
|
-
|
|
106
|
+
const { apiKey } = config.context;
|
|
107
|
+
if (apiKey)
|
|
108
|
+
return (0, exports.humanCredential)(apiKey);
|
|
109
|
+
const { PersonalLoginTokenProvider } = await Promise.resolve().then(() => tslib_1.__importStar(require('./personalLogin/tokenProvider')));
|
|
110
|
+
const login = await new PersonalLoginTokenProvider().getToken(config.context.serverUrl, rejectedGeneration);
|
|
111
|
+
return {
|
|
112
|
+
kind: 'personal_oauth',
|
|
113
|
+
token: login.tokens.accessToken,
|
|
114
|
+
login,
|
|
115
|
+
};
|
|
107
116
|
}
|
|
108
117
|
if (!config.context?.serverUrl ||
|
|
109
118
|
!config.user?.userUuid ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/createApp.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/createApp.ts"],"names":[],"mappings":"AAAA,OAAO,EAOH,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACxB,MAAM,mBAAmB,CAAC;AAyB3B,MAAM,MAAM,uBAAuB,GAAG;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAKF,eAAO,MAAM,6BAA6B,EAAE,gBA4B3C,CAAC;AAEF,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,iBAAiB,YAC1B,QAAQ,EACR,OAAO,EACP,MAAM,EACN,OAAO,EACP,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,OAAO,EACP,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAU,EACV,eAAe,EACf,OAAO,EACP,aAAa,EACb,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,OAAO,EACP,UAAU,EACV,WAAW,CACL,CAAC;AAEX,eAAO,MAAM,mBAAmB,SACtB,MAAM,iBACG,MAAM,KACtB,MAWF,CAAC;AAEF,eAAO,MAAM,qBAAqB,SAAU;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB,KAAG,eAaF,CAAC;AAqLH,eAAO,MAAM,gBAAgB,SACnB,MAAM,WACH,uBAAuB,KACjC,OAAO,CAAC,IAAI,CAsId,CAAC"}
|
|
@@ -240,9 +240,7 @@ const createAppHandler = async (name, options) => {
|
|
|
240
240
|
// user to approve any local package installation.
|
|
241
241
|
await (0, apiClient_1.checkLightdashVersion)();
|
|
242
242
|
const config = await (0, config_1.getConfig)();
|
|
243
|
-
|
|
244
|
-
throw new common_1.AuthorizationError(`Not logged in. Run 'lightdash login --help'`);
|
|
245
|
-
}
|
|
243
|
+
await (0, credentials_1.resolveCredential)(config);
|
|
246
244
|
const projectSelection = await (0, selectProject_1.selectProject)(config, options.project);
|
|
247
245
|
if (!projectSelection) {
|
|
248
246
|
throw new common_1.LightdashError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,mBAAmB,CAAC;AAkB3B,OAAO,EAAqB,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,SAAU;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACjC,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA+CxB,CAAC;AAEF,eAAO,MAAM,wBAAwB,SAAgB;IACjD,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,KAAG,OAAO,CAAC,MAAM,EAAE,CA8EnB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,WACtC,MAAM,KACf,OAAO,CAAC,IAAI,CAWd,CAAC;AAEF,eAAO,MAAM,oBAAoB,SAAgB;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACf,KAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CA2BlD,CAAC;AAQF,eAAO,MAAM,wBAAwB,WACzB,MAAM,KACf,OAAO,CAAC,IAAI,CAMd,CAAC;AAyBF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAAgB;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACtB,KAAG,OAAO,CAAC,IAAI,CAwEf,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,SAAU;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACrB,KAAG,MACgT,CAAC;AAErT,eAAO,MAAM,uBAAuB,SAAgB;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,KAAG,OAAO,CAAC,OAAO,CAoBlB,CAAC;AAKF,eAAO,MAAM,6BAA6B,WAC9B,MAAM,KACf,OAAO,CAAC,OAAO,CAmBjB,CAAC;AAkBF,KAAK,kBAAkB,GAAG;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,sBAAsB,UACxB,qBAAqB,KAC7B,MA4BF,CAAC;AAEF,eAAO,MAAM,kBAAkB,QACtB,MAAM,GAAG,SAAS,KACxB,MAAM,GAAG,SASX,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAClB,MAAM,GAAG,SAAS,WAClB,kBAAkB,KAC5B,OAAO,CAAC,IAAI,CAsJd,CAAC"}
|
|
@@ -369,15 +369,16 @@ const appsPreviewHandler = async (pathArg, options) => {
|
|
|
369
369
|
const devServerPort = (0, exports.resolvePreviewPort)(options.port);
|
|
370
370
|
const config = await (0, config_1.getConfig)();
|
|
371
371
|
const serverUrl = options.url ?? config.context?.serverUrl;
|
|
372
|
-
|
|
373
|
-
// env-var path is safe. The only exposure is an explicit --token on the
|
|
374
|
-
// command line (visible in shell history / `ps aux`) — warn rather than
|
|
375
|
-
// block, since --token is a supported CI path.
|
|
376
|
-
const apiKey = options.token ?? config.context?.apiKey;
|
|
377
|
-
if (!serverUrl || !apiKey) {
|
|
372
|
+
if (!serverUrl) {
|
|
378
373
|
throw new common_1.AuthorizationError(`Not logged in or missing server URL. Run 'lightdash login <url>' first, or set LIGHTDASH_URL and LIGHTDASH_API_KEY.`);
|
|
379
374
|
}
|
|
380
|
-
const
|
|
375
|
+
const resolveAuthorization = async () => (0, utils_1.getCredentialAuthHeader)(options.token
|
|
376
|
+
? (0, credentials_1.humanCredential)(options.token)
|
|
377
|
+
: await (0, credentials_1.resolveCredential)({
|
|
378
|
+
...config,
|
|
379
|
+
context: { ...config.context, serverUrl },
|
|
380
|
+
}));
|
|
381
|
+
const authorization = await resolveAuthorization();
|
|
381
382
|
const proxyAuthorization = config.context?.proxyAuthorization;
|
|
382
383
|
if (options.token) {
|
|
383
384
|
globalState_1.default.log(styles.warning(`Passing --token on the command line exposes it in your shell history and process list. Prefer 'lightdash login' or the LIGHTDASH_API_KEY environment variable.`));
|
|
@@ -403,10 +404,10 @@ const appsPreviewHandler = async (pathArg, options) => {
|
|
|
403
404
|
if (!options.url && !options.token) {
|
|
404
405
|
await (0, apiClient_1.checkLightdashVersion)();
|
|
405
406
|
}
|
|
406
|
-
const preflight = (apiPath) => (0, exports.preflightPreviewRequest)({
|
|
407
|
+
const preflight = async (apiPath) => (0, exports.preflightPreviewRequest)({
|
|
407
408
|
apiPath,
|
|
408
409
|
serverUrl,
|
|
409
|
-
authorization,
|
|
410
|
+
authorization: await resolveAuthorization(),
|
|
410
411
|
proxyAuthorization,
|
|
411
412
|
});
|
|
412
413
|
if (!(await preflight('/api/v1/user'))) {
|
|
@@ -422,7 +423,7 @@ const appsPreviewHandler = async (pathArg, options) => {
|
|
|
422
423
|
manifest,
|
|
423
424
|
projectUuid: target.projectUuid,
|
|
424
425
|
serverUrl,
|
|
425
|
-
authorization,
|
|
426
|
+
authorization: await resolveAuthorization(),
|
|
426
427
|
proxyAuthorization,
|
|
427
428
|
});
|
|
428
429
|
// Previous versions persisted this credential in .env.local. Remove only
|
|
@@ -434,6 +435,7 @@ const appsPreviewHandler = async (pathArg, options) => {
|
|
|
434
435
|
const proxy = await (0, previewProxy_1.startPreviewProxy)({
|
|
435
436
|
upstreamUrl: serverUrl,
|
|
436
437
|
authorization,
|
|
438
|
+
resolveAuthorization,
|
|
437
439
|
proxyAuthorization,
|
|
438
440
|
projectUuid: target.projectUuid,
|
|
439
441
|
nonce: proxyNonce,
|
|
@@ -22,6 +22,7 @@ export type CompiledQueryLogEntry = {
|
|
|
22
22
|
export declare const startPreviewProxy: (args: {
|
|
23
23
|
upstreamUrl: string;
|
|
24
24
|
authorization: string;
|
|
25
|
+
resolveAuthorization?: () => Promise<string>;
|
|
25
26
|
proxyAuthorization?: string;
|
|
26
27
|
projectUuid: string;
|
|
27
28
|
nonce: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"previewProxy.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/previewProxy.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,0BAA0B,8BAA8B,CAAC;AA6CtE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,qBAAqB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAG5B,0BAA0B,EAAE,MAAM,EAAE,CAAC;CACxC,CAAC;AAyCF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,SAAU;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IAGd,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,KAAG,OAAO,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"previewProxy.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/previewProxy.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,0BAA0B,8BAA8B,CAAC;AA6CtE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,qBAAqB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAG5B,0BAA0B,EAAE,MAAM,EAAE,CAAC;CACxC,CAAC;AAyCF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,SAAU;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IAGd,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,KAAG,OAAO,CAAC,kBAAkB,CAyW7B,CAAC"}
|
|
@@ -90,52 +90,68 @@ const startPreviewProxy = (args) => {
|
|
|
90
90
|
: {}),
|
|
91
91
|
});
|
|
92
92
|
// Resolves the parsed body of a successful upstream GET, or null.
|
|
93
|
-
const getUpstreamJson = (path) =>
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
93
|
+
const getUpstreamJson = async (path) => {
|
|
94
|
+
const authorization = args.resolveAuthorization
|
|
95
|
+
? await args.resolveAuthorization()
|
|
96
|
+
: args.authorization;
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
const upstreamReq = requestFn({
|
|
99
|
+
protocol: upstream.protocol,
|
|
100
|
+
hostname: upstream.hostname,
|
|
101
|
+
port: upstream.port || undefined,
|
|
102
|
+
path,
|
|
103
|
+
method: 'GET',
|
|
104
|
+
headers: {
|
|
105
|
+
...withUpstreamCredentials({
|
|
106
|
+
accept: 'application/json',
|
|
107
|
+
}),
|
|
108
|
+
authorization,
|
|
109
|
+
},
|
|
110
|
+
}, (upstreamRes) => {
|
|
111
|
+
readBody(upstreamRes).then((text) => {
|
|
112
|
+
const status = upstreamRes.statusCode ?? 502;
|
|
113
|
+
resolve(status >= 200 && status < 300
|
|
114
|
+
? parseJson(text)
|
|
115
|
+
: null);
|
|
116
|
+
}, () => resolve(null));
|
|
117
|
+
});
|
|
118
|
+
upstreamReq.on('error', () => resolve(null));
|
|
119
|
+
upstreamReq.end();
|
|
110
120
|
});
|
|
111
|
-
|
|
112
|
-
upstreamReq.end();
|
|
113
|
-
});
|
|
121
|
+
};
|
|
114
122
|
// Resolves the parsed body of a successful upstream POST, or null.
|
|
115
|
-
const postUpstreamJson = (path, body) =>
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
'
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
const postUpstreamJson = async (path, body) => {
|
|
124
|
+
const authorization = args.resolveAuthorization
|
|
125
|
+
? await args.resolveAuthorization()
|
|
126
|
+
: args.authorization;
|
|
127
|
+
return new Promise((resolve) => {
|
|
128
|
+
const payload = Buffer.from(body, 'utf-8');
|
|
129
|
+
const upstreamReq = requestFn({
|
|
130
|
+
protocol: upstream.protocol,
|
|
131
|
+
hostname: upstream.hostname,
|
|
132
|
+
port: upstream.port || undefined,
|
|
133
|
+
path,
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: {
|
|
136
|
+
...withUpstreamCredentials({
|
|
137
|
+
accept: 'application/json',
|
|
138
|
+
'content-type': 'application/json',
|
|
139
|
+
'content-length': payload.length,
|
|
140
|
+
}),
|
|
141
|
+
authorization,
|
|
142
|
+
},
|
|
143
|
+
}, (upstreamRes) => {
|
|
144
|
+
readBody(upstreamRes).then((text) => {
|
|
145
|
+
const status = upstreamRes.statusCode ?? 502;
|
|
146
|
+
resolve(status >= 200 && status < 300
|
|
147
|
+
? parseJson(text)
|
|
148
|
+
: null);
|
|
149
|
+
}, () => resolve(null));
|
|
150
|
+
});
|
|
151
|
+
upstreamReq.on('error', () => resolve(null));
|
|
152
|
+
upstreamReq.end(payload);
|
|
135
153
|
});
|
|
136
|
-
|
|
137
|
-
upstreamReq.end(payload);
|
|
138
|
-
});
|
|
154
|
+
};
|
|
139
155
|
// --show-sql: compile the metric query the app just ran (same payload the
|
|
140
156
|
// customer-facing compileQuery endpoint takes) and report the SQL.
|
|
141
157
|
const compileAndReport = async (requestBody) => {
|
|
@@ -205,7 +221,7 @@ const startPreviewProxy = (args) => {
|
|
|
205
221
|
res.writeHead(200, { 'content-type': 'application/json' });
|
|
206
222
|
res.end(JSON.stringify({ status: 'ok', results }));
|
|
207
223
|
};
|
|
208
|
-
const
|
|
224
|
+
const handleRequest = async (req, res) => {
|
|
209
225
|
const method = req.method ?? 'GET';
|
|
210
226
|
const nonceHeader = req.headers[exports.PREVIEW_PROXY_NONCE_HEADER];
|
|
211
227
|
const browserAuthorization = req.headers.authorization;
|
|
@@ -243,6 +259,8 @@ const startPreviewProxy = (args) => {
|
|
|
243
259
|
return;
|
|
244
260
|
}
|
|
245
261
|
const headers = withUpstreamCredentials(filterHeaders(req.headers, DROPPED_REQUEST_HEADERS));
|
|
262
|
+
if (args.resolveAuthorization)
|
|
263
|
+
headers.authorization = await args.resolveAuthorization();
|
|
246
264
|
// The previewed app fetches the export's fileUrl directly from the
|
|
247
265
|
// local dev page, which carries no instance credentials — ask the
|
|
248
266
|
// backend for a SIGNED URL, same as the deployed app's bridge.
|
|
@@ -279,6 +297,14 @@ const startPreviewProxy = (args) => {
|
|
|
279
297
|
else {
|
|
280
298
|
req.pipe(upstreamReq);
|
|
281
299
|
}
|
|
300
|
+
};
|
|
301
|
+
const server = http.createServer((req, res) => {
|
|
302
|
+
handleRequest(req, res).catch(() => {
|
|
303
|
+
if (!res.headersSent)
|
|
304
|
+
sendJsonError(res, 502, 'Preview proxy: could not authenticate the upstream request.');
|
|
305
|
+
else
|
|
306
|
+
res.destroy();
|
|
307
|
+
});
|
|
282
308
|
});
|
|
283
309
|
return new Promise((resolve, reject) => {
|
|
284
310
|
server.once('error', reject);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/apiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,WAAW,EAIX,WAAW,EAEX,KAAK,6BAA6B,EAGrC,MAAM,mBAAmB,CAAC;AAC3B,OAAc,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkB5D,KAAK,iBAAiB,GAAG;IACrB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,KAAK,oBAAoB,GAAG,iBAAiB,GAAG;IAC5C,SAAS,CAAC,EAAE,OAAO,kCAAkC,EAAE,kBAAkB,CAAC;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAKF,eAAO,MAAM,cAAc,YAAa,OAAO,SAE9C,CAAC;AAqDF,eAAO,MAAM,eAAe,oFAQzB,oBAAoB,KAAG,OAAO,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/apiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,WAAW,EAIX,WAAW,EAEX,KAAK,6BAA6B,EAGrC,MAAM,mBAAmB,CAAC;AAC3B,OAAc,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkB5D,KAAK,iBAAiB,GAAG;IACrB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,KAAK,oBAAoB,GAAG,iBAAiB,GAAG;IAC5C,SAAS,CAAC,EAAE,OAAO,kCAAkC,EAAE,kBAAkB,CAAC;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAKF,eAAO,MAAM,cAAc,YAAa,OAAO,SAE9C,CAAC;AAqDF,eAAO,MAAM,eAAe,oFAQzB,oBAAoB,KAAG,OAAO,CAAC,QAAQ,CA6NzC,CAAC;AAEF,eAAO,MAAM,cAAc,aAAoB,QAAQ,KAAG,OAAO,CAAC,OAAO,CAsBxE,CAAC;AA6BF,eAAO,MAAM,YAAY,GAAU,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,+CAMhE,iBAAiB,KAAG,OAAO,CAAC,CAAC,CAiE/B,CAAC;AAEF,eAAO,MAAM,cAAc,QACb,OAAO,CAAC,6BAA6B,CAMzC,CAAC;AAEX,MAAM,MAAM,8BAA8B,GAAG;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,iCAAiC,gBAC7B,MAAM,KACpB,OAAO,CAAC,8BAA8B,CAiGxC,CAAC;AAEF,eAAO,MAAM,8BAA8B,wBAClB,MAAM,GAAG,SAAS,eAC1B,WAAW,KACzB,OAAO,CAAC,IAAI,CA+Gd,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,IAAI,CA8C1D,CAAC"}
|
|
@@ -168,21 +168,32 @@ const lightdashRawApi = async ({ method, url, body, headers: requestHeaders = {}
|
|
|
168
168
|
connectionResponses.add(response);
|
|
169
169
|
return response;
|
|
170
170
|
}
|
|
171
|
-
if (!
|
|
171
|
+
if (!config.context?.serverUrl) {
|
|
172
172
|
throw new common_1.AuthorizationError(`Not logged in. Run 'lightdash login --help'`);
|
|
173
173
|
}
|
|
174
|
-
const headers = {
|
|
175
|
-
...(0, utils_1.buildRequestHeaders)(config.context.apiKey),
|
|
176
|
-
...requestHeaders,
|
|
177
|
-
};
|
|
178
174
|
const fullUrl = new url_1.URL(url, config.context.serverUrl).href;
|
|
179
|
-
|
|
180
|
-
const
|
|
175
|
+
let credential = await (0, credentials_1.resolveCredential)(config);
|
|
176
|
+
const send = () => fetchWithTimeout(fullUrl, {
|
|
181
177
|
method,
|
|
182
|
-
headers
|
|
178
|
+
headers: {
|
|
179
|
+
...(0, utils_1.buildCredentialHeaders)(credential, config.context?.proxyAuthorization ?? null),
|
|
180
|
+
...requestHeaders,
|
|
181
|
+
},
|
|
183
182
|
body,
|
|
184
183
|
signal,
|
|
185
184
|
});
|
|
185
|
+
globalState_1.default.debug(`> Making HTTP ${method} request to: ${fullUrl}`);
|
|
186
|
+
let response = await send();
|
|
187
|
+
if (response.status === 401 &&
|
|
188
|
+
safeToRetry &&
|
|
189
|
+
method === 'GET' &&
|
|
190
|
+
body === undefined &&
|
|
191
|
+
credential.kind === 'personal_oauth') {
|
|
192
|
+
if (response.body instanceof stream_1.Readable)
|
|
193
|
+
response.body.destroy();
|
|
194
|
+
credential = await (0, credentials_1.resolveCredential)(config, null, credential.login.tokens.generation);
|
|
195
|
+
response = await send();
|
|
196
|
+
}
|
|
186
197
|
globalState_1.default.debug(`> HTTP request returned status: ${response.status}`);
|
|
187
198
|
if (!response.ok) {
|
|
188
199
|
const contentType = response.headers.get('content-type');
|
|
@@ -244,10 +255,7 @@ const readApiResults = async (response) => {
|
|
|
244
255
|
}
|
|
245
256
|
};
|
|
246
257
|
const lightdashApi = async ({ method, url, body, signal, safeToRetry, }) => {
|
|
247
|
-
if (
|
|
248
|
-
safeToRetry &&
|
|
249
|
-
method === 'GET' &&
|
|
250
|
-
body === undefined) {
|
|
258
|
+
if (safeToRetry && method === 'GET' && body === undefined) {
|
|
251
259
|
return readApiResults(await (0, exports.lightdashRawApi)({ method, url, body, signal, safeToRetry }));
|
|
252
260
|
}
|
|
253
261
|
const headers = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/handlers/diagnostics.ts"],"names":[],"mappings":"AAiBA,KAAK,kBAAkB,GAAG;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/handlers/diagnostics.ts"],"names":[],"mappings":"AAiBA,KAAK,kBAAkB,GAAG;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AA4HF,eAAO,MAAM,kBAAkB,YAAmB,kBAAkB,kBA4InE,CAAC"}
|
|
@@ -37,7 +37,7 @@ const getAuthStatus = async () => {
|
|
|
37
37
|
const organizationUuid = config.user?.organizationUuid || 'Not set';
|
|
38
38
|
const projectName = config.context?.projectName || 'Not set';
|
|
39
39
|
const projectUuid = config.context?.project || 'Not set';
|
|
40
|
-
if (!
|
|
40
|
+
if (!config.context?.serverUrl) {
|
|
41
41
|
return {
|
|
42
42
|
status: 'missing_credentials',
|
|
43
43
|
serverUrl,
|
|
@@ -47,6 +47,7 @@ const getAuthStatus = async () => {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
try {
|
|
50
|
+
await (0, credentials_1.resolveCredential)(config);
|
|
50
51
|
const user = await (0, apiClient_1.getUserContext)();
|
|
51
52
|
return {
|
|
52
53
|
status: 'authenticated',
|