apify-cli 1.0.0-beta.13 → 1.0.0-beta.15
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 +46 -44
- package/dist/.tsbuildinfo +1 -1
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +143 -12
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/secrets/index.js +1 -1
- package/dist/lib/secrets.js +3 -3
- package/oclif.manifest.json +13 -30
- package/package.json +4 -3
- package/dist/commands/login-new.d.ts +0 -10
- package/dist/commands/login-new.d.ts.map +0 -1
- package/dist/commands/login-new.js +0 -166
- package/dist/commands/login-new.js.map +0 -1
package/dist/commands/login.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare class LoginCommand extends ApifyCommand<typeof LoginCommand> {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static flags: {
|
|
5
5
|
token: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
6
|
+
method: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
6
7
|
};
|
|
7
8
|
run(): Promise<void>;
|
|
8
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AA0BvD,qBAAa,YAAa,SAAQ,YAAY,CAAC,OAAO,YAAY,CAAC;IAC/D,OAAgB,WAAW,SAEU;IAErC,OAAgB,KAAK;;;MAYnB;IAEI,GAAG;CA6HZ"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,30 +1,155 @@
|
|
|
1
|
+
import { cryptoRandomObjectId } from '@apify/utilities';
|
|
1
2
|
import { Flags } from '@oclif/core';
|
|
3
|
+
import computerName from 'computer-name';
|
|
4
|
+
import cors from 'cors';
|
|
5
|
+
import express from 'express';
|
|
2
6
|
import inquirer from 'inquirer';
|
|
7
|
+
import open from 'open';
|
|
3
8
|
import { ApifyCommand } from '../lib/apify_command.js';
|
|
4
|
-
import { error, success } from '../lib/outputs.js';
|
|
9
|
+
import { error, info, success } from '../lib/outputs.js';
|
|
5
10
|
import { useApifyIdentity } from '../lib/telemetry.js';
|
|
6
11
|
import { getLocalUserInfo, getLoggedClient } from '../lib/utils.js';
|
|
12
|
+
const CONSOLE_BASE_URL = 'https://console.apify.com/account?tab=integrations';
|
|
13
|
+
// const CONSOLE_BASE_URL = 'http://localhost:3000/account?tab=integrations';
|
|
14
|
+
const CONSOLE_URL_ORIGIN = new URL(CONSOLE_BASE_URL).origin;
|
|
15
|
+
const API_BASE_URL = CONSOLE_BASE_URL.includes('localhost') ? 'http://localhost:3333' : undefined;
|
|
16
|
+
// Not really checked right now, but it might come useful if we ever need to do some breaking changes
|
|
17
|
+
const API_VERSION = 'v1';
|
|
18
|
+
const tryToLogin = async (token) => {
|
|
19
|
+
const isUserLogged = await getLoggedClient(token, API_BASE_URL);
|
|
20
|
+
const userInfo = await getLocalUserInfo();
|
|
21
|
+
if (isUserLogged) {
|
|
22
|
+
await useApifyIdentity(userInfo.id);
|
|
23
|
+
success(`You are logged in to Apify as ${userInfo.username || userInfo.id}!`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
error('Login to Apify failed, the provided API token is not valid.');
|
|
27
|
+
}
|
|
28
|
+
return isUserLogged;
|
|
29
|
+
};
|
|
7
30
|
export class LoginCommand extends ApifyCommand {
|
|
8
31
|
async run() {
|
|
9
|
-
|
|
10
|
-
if (
|
|
32
|
+
const { token, method } = this.flags;
|
|
33
|
+
if (token) {
|
|
34
|
+
await tryToLogin(token);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
let selectedMethod = method;
|
|
38
|
+
if (!method) {
|
|
39
|
+
const answer = await inquirer.prompt([{
|
|
40
|
+
type: 'list',
|
|
41
|
+
name: 'loginMethod',
|
|
42
|
+
message: 'Choose how you want to log in to Apify',
|
|
43
|
+
choices: [
|
|
44
|
+
{
|
|
45
|
+
value: 'console',
|
|
46
|
+
name: 'Through Apify Console in your default browser',
|
|
47
|
+
short: 'Through Apify Console',
|
|
48
|
+
},
|
|
49
|
+
{ value: 'manual', name: 'Enter API token manually', short: 'Manually' },
|
|
50
|
+
],
|
|
51
|
+
loop: true,
|
|
52
|
+
}]);
|
|
53
|
+
selectedMethod = answer.loginMethod;
|
|
54
|
+
}
|
|
55
|
+
if (selectedMethod === 'console') {
|
|
56
|
+
let server;
|
|
57
|
+
const app = express();
|
|
58
|
+
// To send requests from browser to localhost, CORS has to be configured properly
|
|
59
|
+
app.use(cors({
|
|
60
|
+
origin: CONSOLE_URL_ORIGIN,
|
|
61
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
62
|
+
}));
|
|
63
|
+
// Turn off keepalive, otherwise closing the server when command is finished is lagging
|
|
64
|
+
app.use((_, res, next) => {
|
|
65
|
+
res.set('Connection', 'close');
|
|
66
|
+
next();
|
|
67
|
+
});
|
|
68
|
+
app.use(express.json());
|
|
69
|
+
// Basic authorization via a random token, which is passed to the Apify Console,
|
|
70
|
+
// and that sends it back via the `token` query param, or `Authorization` header
|
|
71
|
+
const authToken = cryptoRandomObjectId();
|
|
72
|
+
app.use((req, res, next) => {
|
|
73
|
+
let { token: serverToken } = req.query;
|
|
74
|
+
if (!serverToken) {
|
|
75
|
+
const authorizationHeader = req.get('Authorization');
|
|
76
|
+
if (authorizationHeader) {
|
|
77
|
+
const [schema, tokenFromHeader, ...extra] = authorizationHeader.trim().split(/\s+/);
|
|
78
|
+
if (schema.toLowerCase() === 'bearer' && tokenFromHeader && extra.length === 0) {
|
|
79
|
+
serverToken = tokenFromHeader;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (serverToken !== authToken) {
|
|
84
|
+
res.status(401);
|
|
85
|
+
res.send('Authorization failed');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
next();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const apiRouter = express.Router();
|
|
92
|
+
app.use(`/api/${API_VERSION}`, apiRouter);
|
|
93
|
+
apiRouter.post('/login-token', async (req, res) => {
|
|
94
|
+
try {
|
|
95
|
+
if (req.body.apiToken) {
|
|
96
|
+
await tryToLogin(req.body.apiToken);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
throw new Error('Request did not contain API token');
|
|
100
|
+
}
|
|
101
|
+
res.end();
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const errorMessage = `Login to Apify failed with error: ${err.message}`;
|
|
105
|
+
error(errorMessage);
|
|
106
|
+
res.status(500);
|
|
107
|
+
res.send(errorMessage);
|
|
108
|
+
}
|
|
109
|
+
server.close();
|
|
110
|
+
});
|
|
111
|
+
apiRouter.post('/exit', (req, res) => {
|
|
112
|
+
if (req.body.isWindowClosed) {
|
|
113
|
+
error('Login to Apify failed, the console window was closed.');
|
|
114
|
+
}
|
|
115
|
+
else if (req.body.actionCanceled) {
|
|
116
|
+
error('Login to Apify failed, the action was canceled in the Apify Console.');
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
error('Login to Apify failed.');
|
|
120
|
+
}
|
|
121
|
+
res.end();
|
|
122
|
+
server.close();
|
|
123
|
+
});
|
|
124
|
+
// Listening on port 0 will assign a random available port
|
|
125
|
+
server = app.listen(0);
|
|
126
|
+
const { port } = server.address();
|
|
127
|
+
const consoleUrl = new URL(CONSOLE_BASE_URL);
|
|
128
|
+
consoleUrl.searchParams.set('localCliCommand', 'login');
|
|
129
|
+
consoleUrl.searchParams.set('localCliPort', `${port}`);
|
|
130
|
+
consoleUrl.searchParams.set('localCliToken', authToken);
|
|
131
|
+
consoleUrl.searchParams.set('localCliApiVersion', API_VERSION);
|
|
132
|
+
try {
|
|
133
|
+
consoleUrl.searchParams.set('localCliComputerName', encodeURIComponent(computerName()));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Ignore errors from fetching computer name as it's not critical
|
|
137
|
+
}
|
|
138
|
+
info(`Opening Apify Console at "${consoleUrl.href}"...`);
|
|
139
|
+
await open(consoleUrl.href);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
11
142
|
console.log('Enter your Apify API token. You can find it at https://console.apify.com/account#/integrations');
|
|
12
|
-
const
|
|
13
|
-
(
|
|
143
|
+
const tokenAnswer = await inquirer.prompt([{ name: 'token', message: 'token:', type: 'password' }]);
|
|
144
|
+
await tryToLogin(tokenAnswer.token);
|
|
14
145
|
}
|
|
15
|
-
const isUserLogged = await getLoggedClient(token);
|
|
16
|
-
const userInfo = await getLocalUserInfo();
|
|
17
|
-
await useApifyIdentity(userInfo.id);
|
|
18
|
-
return isUserLogged
|
|
19
|
-
? success(`You are logged in to Apify as ${userInfo.username || userInfo.id}!`)
|
|
20
|
-
: error('Login to Apify failed, the provided API token is not valid.');
|
|
21
146
|
}
|
|
22
147
|
}
|
|
23
148
|
Object.defineProperty(LoginCommand, "description", {
|
|
24
149
|
enumerable: true,
|
|
25
150
|
configurable: true,
|
|
26
151
|
writable: true,
|
|
27
|
-
value: 'Logs in to your Apify account
|
|
152
|
+
value: 'Logs in to your Apify account.\nThe API token and other account '
|
|
28
153
|
+ 'information is stored in the ~/.apify directory, from where it is read by all other "apify" commands. '
|
|
29
154
|
+ 'To log out, call "apify logout".'
|
|
30
155
|
});
|
|
@@ -38,6 +163,12 @@ Object.defineProperty(LoginCommand, "flags", {
|
|
|
38
163
|
description: '[Optional] Apify API token',
|
|
39
164
|
required: false,
|
|
40
165
|
}),
|
|
166
|
+
method: Flags.string({
|
|
167
|
+
char: 'm',
|
|
168
|
+
description: '[Optional] Method of logging in to Apify',
|
|
169
|
+
options: ['console', 'manual'],
|
|
170
|
+
required: false,
|
|
171
|
+
}),
|
|
41
172
|
}
|
|
42
173
|
});
|
|
43
174
|
//# sourceMappingURL=login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ Object.defineProperty(SecretsIndexCommand, "description", {
|
|
|
11
11
|
writable: true,
|
|
12
12
|
value: 'Manages secret values for Actor environment variables.\n\n'
|
|
13
13
|
+ 'Example:\n'
|
|
14
|
-
+ '$ apify secrets
|
|
14
|
+
+ '$ apify secrets add mySecret TopSecretValue123\n\n'
|
|
15
15
|
+ `Now the "mySecret" value can be used in an environment variable defined in "${LOCAL_CONFIG_PATH}" file by adding the "@" prefix:\n\n`
|
|
16
16
|
+ '{\n'
|
|
17
17
|
+ ' "actorSpecification": 1,\n'
|
package/dist/lib/secrets.js
CHANGED
|
@@ -24,7 +24,7 @@ const writeSecretsFile = (secrets) => {
|
|
|
24
24
|
export const addSecret = (name, value) => {
|
|
25
25
|
const secrets = getSecretsFile();
|
|
26
26
|
if (secrets[name])
|
|
27
|
-
throw new Error(`Secret with name ${name} already exists. Call "apify secrets
|
|
27
|
+
throw new Error(`Secret with name ${name} already exists. Call "apify secrets rm ${name}" to remove it.`);
|
|
28
28
|
if (!_.isString(name) || name.length > MAX_ENV_VAR_NAME_LENGTH) {
|
|
29
29
|
throw new Error(`Secret name has to be string with maximum length ${MAX_ENV_VAR_NAME_LENGTH}.`);
|
|
30
30
|
}
|
|
@@ -60,7 +60,7 @@ export const replaceSecretsValue = (env, secrets) => {
|
|
|
60
60
|
updatedEnv[key] = secrets[secretKey];
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
63
|
-
warning(`Value for ${secretKey} not found in local secrets. Set it by calling "apify secrets
|
|
63
|
+
warning(`Value for ${secretKey} not found in local secrets. Set it by calling "apify secrets add ${secretKey} [SECRET_VALUE]"`);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
else {
|
|
@@ -89,7 +89,7 @@ export const transformEnvToEnvVars = (env, secrets) => {
|
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
92
|
-
warning(`Value for ${secretKey} not found in local secrets. Set it by calling "apify secrets
|
|
92
|
+
warning(`Value for ${secretKey} not found in local secrets. Set it by calling "apify secrets add ${secretKey} [SECRET_VALUE]"`);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
else {
|
package/oclif.manifest.json
CHANGED
|
@@ -251,10 +251,10 @@
|
|
|
251
251
|
"init.js"
|
|
252
252
|
]
|
|
253
253
|
},
|
|
254
|
-
"login
|
|
254
|
+
"login": {
|
|
255
255
|
"aliases": [],
|
|
256
256
|
"args": {},
|
|
257
|
-
"description": "Logs in to your Apify account
|
|
257
|
+
"description": "Logs in to your Apify account.\nThe API token and other account information is stored in the ~/.apify directory, from where it is read by all other \"apify\" commands. To log out, call \"apify logout\".",
|
|
258
258
|
"flags": {
|
|
259
259
|
"token": {
|
|
260
260
|
"char": "t",
|
|
@@ -264,35 +264,18 @@
|
|
|
264
264
|
"hasDynamicHelp": false,
|
|
265
265
|
"multiple": false,
|
|
266
266
|
"type": "option"
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
"id": "login-new",
|
|
273
|
-
"pluginAlias": "apify-cli",
|
|
274
|
-
"pluginName": "apify-cli",
|
|
275
|
-
"pluginType": "core",
|
|
276
|
-
"strict": true,
|
|
277
|
-
"isESM": true,
|
|
278
|
-
"relativePath": [
|
|
279
|
-
"dist",
|
|
280
|
-
"commands",
|
|
281
|
-
"login-new.js"
|
|
282
|
-
]
|
|
283
|
-
},
|
|
284
|
-
"login": {
|
|
285
|
-
"aliases": [],
|
|
286
|
-
"args": {},
|
|
287
|
-
"description": "Logs in to your Apify account using a provided API token.\nThe API token and other account information is stored in the ~/.apify directory, from where it is read by all other \"apify\" commands. To log out, call \"apify logout\".",
|
|
288
|
-
"flags": {
|
|
289
|
-
"token": {
|
|
290
|
-
"char": "t",
|
|
291
|
-
"description": "[Optional] Apify API token",
|
|
292
|
-
"name": "token",
|
|
267
|
+
},
|
|
268
|
+
"method": {
|
|
269
|
+
"char": "m",
|
|
270
|
+
"description": "[Optional] Method of logging in to Apify",
|
|
271
|
+
"name": "method",
|
|
293
272
|
"required": false,
|
|
294
273
|
"hasDynamicHelp": false,
|
|
295
274
|
"multiple": false,
|
|
275
|
+
"options": [
|
|
276
|
+
"console",
|
|
277
|
+
"manual"
|
|
278
|
+
],
|
|
296
279
|
"type": "option"
|
|
297
280
|
}
|
|
298
281
|
},
|
|
@@ -681,7 +664,7 @@
|
|
|
681
664
|
"secrets": {
|
|
682
665
|
"aliases": [],
|
|
683
666
|
"args": {},
|
|
684
|
-
"description": "Manages secret values for Actor environment variables.\n\nExample:\n$ apify secrets
|
|
667
|
+
"description": "Manages secret values for Actor environment variables.\n\nExample:\n$ apify secrets add mySecret TopSecretValue123\n\nNow the \"mySecret\" value can be used in an environment variable defined in \".actor/actor.json\" file by adding the \"@\" prefix:\n\n{\n \"actorSpecification\": 1,\n \"name\": \"my_actor\",\n \"environmentVariables\": { \"SECRET_ENV_VAR\": \"@mySecret\" },\n \"version\": \"0.1\n}\n\nWhen the Actor is pushed to Apify cloud, the \"SECRET_ENV_VAR\" and its value is stored as a secret environment variable of the Actor.",
|
|
685
668
|
"flags": {},
|
|
686
669
|
"hasDynamicHelp": false,
|
|
687
670
|
"hiddenAliases": [],
|
|
@@ -725,5 +708,5 @@
|
|
|
725
708
|
]
|
|
726
709
|
}
|
|
727
710
|
},
|
|
728
|
-
"version": "1.0.0-beta.
|
|
711
|
+
"version": "1.0.0-beta.15"
|
|
729
712
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apify-cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"description": "Apify command-line interface (CLI) helps you manage the Apify cloud platform and develop, build, and deploy Apify Actors.",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@apify/input_schema": "~3.5.15",
|
|
61
61
|
"@apify/utilities": "~2.10.0",
|
|
62
62
|
"@crawlee/memory-storage": "~3.8.1",
|
|
63
|
-
"@oclif/core": "~3.
|
|
63
|
+
"@oclif/core": "~3.25.0",
|
|
64
64
|
"@oclif/plugin-help": "~6.0.14",
|
|
65
65
|
"@root/walk": "~1.1.0",
|
|
66
66
|
"adm-zip": "~0.5.10",
|
|
@@ -138,7 +138,8 @@
|
|
|
138
138
|
],
|
|
139
139
|
"additionalVersionFlags": [
|
|
140
140
|
"-v"
|
|
141
|
-
]
|
|
141
|
+
],
|
|
142
|
+
"topicSeparator": " "
|
|
142
143
|
},
|
|
143
144
|
"volta": {
|
|
144
145
|
"node": "20.11.1",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ApifyCommand } from '../lib/apify_command.js';
|
|
2
|
-
export declare class LoginNewCommand extends ApifyCommand<typeof LoginNewCommand> {
|
|
3
|
-
static description: string;
|
|
4
|
-
static flags: {
|
|
5
|
-
token: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
6
|
-
};
|
|
7
|
-
static hidden: boolean;
|
|
8
|
-
run(): Promise<void>;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=login-new.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"login-new.d.ts","sourceRoot":"","sources":["../../src/commands/login-new.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AA0BvD,qBAAa,eAAgB,SAAQ,YAAY,CAAC,OAAO,eAAe,CAAC;IACrE,OAAgB,WAAW,SAEU;IAErC,OAAgB,KAAK;;MAMnB;IAEF,OAAgB,MAAM,UAAQ;IAExB,GAAG;CAoHZ"}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { cryptoRandomObjectId } from '@apify/utilities';
|
|
2
|
-
import { Flags } from '@oclif/core';
|
|
3
|
-
import computerName from 'computer-name';
|
|
4
|
-
import cors from 'cors';
|
|
5
|
-
import express from 'express';
|
|
6
|
-
import inquirer from 'inquirer';
|
|
7
|
-
import open from 'open';
|
|
8
|
-
import { ApifyCommand } from '../lib/apify_command.js';
|
|
9
|
-
import { error, info, success, warning } from '../lib/outputs.js';
|
|
10
|
-
import { useApifyIdentity } from '../lib/telemetry.js';
|
|
11
|
-
import { getLocalUserInfo, getLoggedClient } from '../lib/utils.js';
|
|
12
|
-
const CONSOLE_BASE_URL = 'https://console.apify.com/account?tab=integrations';
|
|
13
|
-
// const CONSOLE_BASE_URL = 'http://localhost:3000/account?tab=integrations';
|
|
14
|
-
const CONSOLE_URL_ORIGIN = new URL(CONSOLE_BASE_URL).origin;
|
|
15
|
-
const API_BASE_URL = CONSOLE_BASE_URL.includes('localhost') ? 'http://localhost:3333' : undefined;
|
|
16
|
-
// Not really checked right now, but it might come useful if we ever need to do some breaking changes
|
|
17
|
-
const API_VERSION = 'v1';
|
|
18
|
-
const tryToLogin = async (token) => {
|
|
19
|
-
const isUserLogged = await getLoggedClient(token, API_BASE_URL);
|
|
20
|
-
const userInfo = await getLocalUserInfo();
|
|
21
|
-
if (isUserLogged) {
|
|
22
|
-
await useApifyIdentity(userInfo.id);
|
|
23
|
-
success(`You are logged in to Apify as ${userInfo.username || userInfo.id}!`);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
error('Login to Apify failed, the provided API token is not valid.');
|
|
27
|
-
}
|
|
28
|
-
return isUserLogged;
|
|
29
|
-
};
|
|
30
|
-
export class LoginNewCommand extends ApifyCommand {
|
|
31
|
-
async run() {
|
|
32
|
-
warning('This command is still experimental and might break at any time. Use at your own risk.\n');
|
|
33
|
-
const { token } = this.flags;
|
|
34
|
-
if (token) {
|
|
35
|
-
await tryToLogin(token);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const answer = await inquirer.prompt([{
|
|
39
|
-
type: 'list',
|
|
40
|
-
name: 'loginMethod',
|
|
41
|
-
message: 'Choose how you want to log in to Apify',
|
|
42
|
-
choices: [
|
|
43
|
-
{ value: 'console', name: 'Through Apify Console in your default browser', short: 'Through Apify Console' },
|
|
44
|
-
{ value: 'manual', name: 'Enter API token manually', short: 'Manually' },
|
|
45
|
-
],
|
|
46
|
-
loop: false,
|
|
47
|
-
}]);
|
|
48
|
-
if (answer.loginMethod === 'console') {
|
|
49
|
-
let server;
|
|
50
|
-
const app = express();
|
|
51
|
-
// To send requests from browser to localhost, CORS has to be configured properly
|
|
52
|
-
app.use(cors({
|
|
53
|
-
origin: CONSOLE_URL_ORIGIN,
|
|
54
|
-
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
55
|
-
}));
|
|
56
|
-
// Turn off keepalive, otherwise closing the server when command is finished is lagging
|
|
57
|
-
app.use((_, res, next) => {
|
|
58
|
-
res.set('Connection', 'close');
|
|
59
|
-
next();
|
|
60
|
-
});
|
|
61
|
-
app.use(express.json());
|
|
62
|
-
// Basic authorization via a random token, which is passed to the Apify Console,
|
|
63
|
-
// and that sends it back via the `token` query param, or `Authorization` header
|
|
64
|
-
const authToken = cryptoRandomObjectId();
|
|
65
|
-
app.use((req, res, next) => {
|
|
66
|
-
let { token: serverToken } = req.query;
|
|
67
|
-
if (!serverToken) {
|
|
68
|
-
const authorizationHeader = req.get('Authorization');
|
|
69
|
-
if (authorizationHeader) {
|
|
70
|
-
const [schema, tokenFromHeader, ...extra] = authorizationHeader.trim().split(/\s+/);
|
|
71
|
-
if (schema.toLowerCase() === 'bearer' && tokenFromHeader && extra.length === 0) {
|
|
72
|
-
serverToken = tokenFromHeader;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (serverToken !== authToken) {
|
|
77
|
-
res.status(401);
|
|
78
|
-
res.send('Authorization failed');
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
next();
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
const apiRouter = express.Router();
|
|
85
|
-
app.use(`/api/${API_VERSION}`, apiRouter);
|
|
86
|
-
apiRouter.post('/login-token', async (req, res) => {
|
|
87
|
-
try {
|
|
88
|
-
if (req.body.apiToken) {
|
|
89
|
-
await tryToLogin(req.body.apiToken);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
throw new Error('Request did not contain API token');
|
|
93
|
-
}
|
|
94
|
-
res.end();
|
|
95
|
-
}
|
|
96
|
-
catch (err) {
|
|
97
|
-
const errorMessage = `Login to Apify failed with error: ${err.message}`;
|
|
98
|
-
error(errorMessage);
|
|
99
|
-
res.status(500);
|
|
100
|
-
res.send(errorMessage);
|
|
101
|
-
}
|
|
102
|
-
server.close();
|
|
103
|
-
});
|
|
104
|
-
apiRouter.post('/exit', (req, res) => {
|
|
105
|
-
if (req.body.isWindowClosed) {
|
|
106
|
-
error('Login to Apify failed, the console window was closed.');
|
|
107
|
-
}
|
|
108
|
-
else if (req.body.actionCanceled) {
|
|
109
|
-
error('Login to Apify failed, the action was canceled in the Apify Console.');
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
error('Login to Apify failed.');
|
|
113
|
-
}
|
|
114
|
-
res.end();
|
|
115
|
-
server.close();
|
|
116
|
-
});
|
|
117
|
-
// Listening on port 0 will assign a random available port
|
|
118
|
-
server = app.listen(0);
|
|
119
|
-
const { port } = server.address();
|
|
120
|
-
const consoleUrl = new URL(CONSOLE_BASE_URL);
|
|
121
|
-
consoleUrl.searchParams.set('localCliCommand', 'login');
|
|
122
|
-
consoleUrl.searchParams.set('localCliPort', `${port}`);
|
|
123
|
-
consoleUrl.searchParams.set('localCliToken', authToken);
|
|
124
|
-
consoleUrl.searchParams.set('localCliApiVersion', API_VERSION);
|
|
125
|
-
try {
|
|
126
|
-
consoleUrl.searchParams.set('localCliComputerName', encodeURIComponent(computerName()));
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
// Ignore errors from fetching computer name as it's not critical
|
|
130
|
-
}
|
|
131
|
-
info(`Opening Apify Console at "${consoleUrl.href}"...`);
|
|
132
|
-
await open(consoleUrl.href);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
const tokenAnswer = await inquirer.prompt([{ name: 'token', message: 'Insert your Apify API token', type: 'password' }]);
|
|
136
|
-
await tryToLogin(tokenAnswer.token);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
Object.defineProperty(LoginNewCommand, "description", {
|
|
141
|
-
enumerable: true,
|
|
142
|
-
configurable: true,
|
|
143
|
-
writable: true,
|
|
144
|
-
value: 'Logs in to your Apify account using your API token.\nThe API token and other account '
|
|
145
|
-
+ 'information is stored in the ~/.apify directory, from where it is read by all other "apify" commands. '
|
|
146
|
-
+ 'To log out, call "apify logout".'
|
|
147
|
-
});
|
|
148
|
-
Object.defineProperty(LoginNewCommand, "flags", {
|
|
149
|
-
enumerable: true,
|
|
150
|
-
configurable: true,
|
|
151
|
-
writable: true,
|
|
152
|
-
value: {
|
|
153
|
-
token: Flags.string({
|
|
154
|
-
char: 't',
|
|
155
|
-
description: '[Optional] Apify API token',
|
|
156
|
-
required: false,
|
|
157
|
-
}),
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
Object.defineProperty(LoginNewCommand, "hidden", {
|
|
161
|
-
enumerable: true,
|
|
162
|
-
configurable: true,
|
|
163
|
-
writable: true,
|
|
164
|
-
value: true
|
|
165
|
-
});
|
|
166
|
-
//# sourceMappingURL=login-new.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"login-new.js","sourceRoot":"","sources":["../../src/commands/login-new.ts"],"names":[],"mappings":"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"}
|