@sentio/sdk 1.26.4 → 1.27.1
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/aptos/aptos-processor.d.ts +1 -1
- package/lib/aptos/aptos-processor.js +2 -2
- package/lib/aptos/aptos-processor.js.map +1 -1
- package/lib/aptos/index.d.ts +1 -1
- package/lib/aptos/index.js +2 -1
- package/lib/aptos/index.js.map +1 -1
- package/lib/aptos-codegen/codegen.js +6 -18
- package/lib/aptos-codegen/codegen.js.map +1 -1
- package/lib/builtin/aptos/0x1.d.ts +18 -18
- package/lib/builtin/aptos/0x1.js.map +1 -1
- package/lib/builtin/aptos/0x3.d.ts +14 -3
- package/lib/builtin/aptos/0x3.js.map +1 -1
- package/lib/cli/cli.js +3 -3
- package/lib/cli/cli.js.map +1 -1
- package/lib/cli/commands/login-server.d.ts +7 -0
- package/lib/cli/commands/login-server.js +134 -0
- package/lib/cli/commands/login-server.js.map +1 -0
- package/lib/cli/commands/run-login.js +77 -27
- package/lib/cli/commands/run-login.js.map +1 -1
- package/lib/cli/config.d.ts +5 -0
- package/lib/cli/config.js +28 -1
- package/lib/cli/config.js.map +1 -1
- package/package.json +7 -2
- package/src/aptos/aptos-processor.ts +2 -2
- package/src/aptos/index.ts +1 -1
- package/src/aptos-codegen/codegen.ts +7 -23
- package/src/builtin/aptos/0x1.ts +19 -18
- package/src/builtin/aptos/0x3.ts +14 -6
- package/src/cli/cli.ts +3 -3
- package/src/cli/commands/login-server.ts +120 -0
- package/src/cli/commands/run-login.ts +59 -28
- package/src/cli/config.ts +29 -0
package/src/cli/cli.ts
CHANGED
@@ -10,9 +10,9 @@ import { finalizeHost, FinalizeProjectName, SentioProjectConfig } from './config
|
|
10
10
|
import { uploadFile } from './upload'
|
11
11
|
import chalk from 'chalk'
|
12
12
|
import { buildProcessor } from './build'
|
13
|
-
import { runLogin } from './commands/run-login'
|
14
13
|
import { runCreate } from './commands/run-create'
|
15
14
|
import { runVersion } from './commands/run-version'
|
15
|
+
import { runLogin } from './commands/run-login'
|
16
16
|
|
17
17
|
const mainDefinitions = [{ name: 'command', defaultOption: true }]
|
18
18
|
const mainOptions = commandLineArgs(mainDefinitions, {
|
@@ -159,12 +159,12 @@ function usage() {
|
|
159
159
|
header: 'Usage',
|
160
160
|
content: [
|
161
161
|
'sentio <command> --help\t\tshow detail usage of specific command',
|
162
|
-
'sentio login
|
162
|
+
'sentio login\t\t\t\tlogin to sentio',
|
163
163
|
'sentio create\t\t\t\tcreate a template project',
|
164
164
|
'sentio upload\t\t\t\tbuild and upload processor to sentio',
|
165
165
|
'sentio gen\t\t\t\tgenerate abi',
|
166
166
|
'sentio build\t\t\t\tgenerate abi and build',
|
167
|
-
'sentio version\t\t\
|
167
|
+
'sentio version\t\t\tcurrent cli version',
|
168
168
|
],
|
169
169
|
},
|
170
170
|
])
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import express from 'express'
|
2
|
+
import { getAuthConfig, getFinalizedHost } from '../config'
|
3
|
+
import url, { URL } from 'url'
|
4
|
+
import fetch from 'node-fetch'
|
5
|
+
import { getCliVersion } from '../utils'
|
6
|
+
import { WriteKey } from '../key'
|
7
|
+
import chalk from 'chalk'
|
8
|
+
import http from 'http'
|
9
|
+
import os from 'os'
|
10
|
+
import * as crypto from 'crypto'
|
11
|
+
|
12
|
+
interface AuthParams {
|
13
|
+
serverPort: number
|
14
|
+
sentioHost: string
|
15
|
+
codeVerifier: string
|
16
|
+
}
|
17
|
+
|
18
|
+
const app = express()
|
19
|
+
|
20
|
+
let server: http.Server
|
21
|
+
let authParams: AuthParams
|
22
|
+
|
23
|
+
export function startServer(params: AuthParams) {
|
24
|
+
authParams = params
|
25
|
+
server = app.listen(params.serverPort)
|
26
|
+
}
|
27
|
+
|
28
|
+
app.get('/callback', async (req, res) => {
|
29
|
+
res.end('login success, please go back to CLI to continue')
|
30
|
+
const host = authParams.sentioHost
|
31
|
+
const code = req.query.code
|
32
|
+
if (!code || (code as string).length == 0) {
|
33
|
+
return
|
34
|
+
}
|
35
|
+
|
36
|
+
// exchange token
|
37
|
+
const tokenResRaw = await getToken(host, code as string)
|
38
|
+
if (!tokenResRaw.ok) {
|
39
|
+
console.error(chalk.red('request token error, code:', tokenResRaw.status, tokenResRaw.statusText))
|
40
|
+
return
|
41
|
+
}
|
42
|
+
const tokenRes = await tokenResRaw.json()
|
43
|
+
const accessToken = tokenRes['access_token']
|
44
|
+
|
45
|
+
// check if the account is ready
|
46
|
+
const realHost = getFinalizedHost(host)
|
47
|
+
const userResRaw = await getUser(realHost, accessToken)
|
48
|
+
if (!userResRaw.ok) {
|
49
|
+
if (userResRaw.status == 401) {
|
50
|
+
console.error(chalk.red('please sign up on sentio first'))
|
51
|
+
} else {
|
52
|
+
console.error(chalk.red('get user error, code:', userResRaw.status, userResRaw.statusText))
|
53
|
+
}
|
54
|
+
return
|
55
|
+
}
|
56
|
+
const userRes = await userResRaw.json()
|
57
|
+
if (!userRes.emailVerified) {
|
58
|
+
console.error(chalk.red('please verify your email first'))
|
59
|
+
return
|
60
|
+
}
|
61
|
+
|
62
|
+
// create API key
|
63
|
+
const apiKeyName = `${os.hostname()}-${crypto.randomBytes(4).toString('hex')}`
|
64
|
+
const createApiKeyResRaw = await createApiKey(realHost, apiKeyName, 'sdk_generated', accessToken)
|
65
|
+
if (!createApiKeyResRaw.ok) {
|
66
|
+
console.error(chalk.red('create api key error, code:', createApiKeyResRaw.status, createApiKeyResRaw.statusText))
|
67
|
+
return
|
68
|
+
}
|
69
|
+
const createApiKeyRes = await createApiKeyResRaw.json()
|
70
|
+
const apiKey = createApiKeyRes['key']
|
71
|
+
WriteKey(realHost, apiKey)
|
72
|
+
console.log(chalk.green('login success, new API key: ' + apiKey))
|
73
|
+
|
74
|
+
server.close()
|
75
|
+
})
|
76
|
+
|
77
|
+
async function getToken(host: string, code: string) {
|
78
|
+
const authConf = getAuthConfig(host)
|
79
|
+
const params = new url.URLSearchParams({
|
80
|
+
grant_type: 'authorization_code',
|
81
|
+
client_id: authConf.clientId,
|
82
|
+
code_verifier: authParams.codeVerifier,
|
83
|
+
code: code,
|
84
|
+
redirect_uri: `http://localhost:${authParams.serverPort}/callback`,
|
85
|
+
})
|
86
|
+
return fetch(`${authConf.domain}/oauth/token`, {
|
87
|
+
method: 'POST',
|
88
|
+
headers: {
|
89
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
90
|
+
},
|
91
|
+
body: params.toString(),
|
92
|
+
})
|
93
|
+
}
|
94
|
+
|
95
|
+
async function createApiKey(host: string, name: string, source: string, accessToken: string) {
|
96
|
+
const createApiKeyUrl = new URL('/api/v1/keys', host)
|
97
|
+
return fetch(createApiKeyUrl, {
|
98
|
+
method: 'POST',
|
99
|
+
headers: {
|
100
|
+
Authorization: 'Bearer ' + accessToken,
|
101
|
+
version: getCliVersion(),
|
102
|
+
},
|
103
|
+
body: JSON.stringify({
|
104
|
+
name: name,
|
105
|
+
scopes: ['write:project'],
|
106
|
+
source: source,
|
107
|
+
}),
|
108
|
+
})
|
109
|
+
}
|
110
|
+
|
111
|
+
async function getUser(host: string, accessToken: string) {
|
112
|
+
const getUserUrl = new URL('/api/v1/users', host)
|
113
|
+
return fetch(getUserUrl, {
|
114
|
+
method: 'GET',
|
115
|
+
headers: {
|
116
|
+
Authorization: 'Bearer ' + accessToken,
|
117
|
+
version: getCliVersion(),
|
118
|
+
},
|
119
|
+
})
|
120
|
+
}
|
@@ -1,10 +1,14 @@
|
|
1
1
|
import commandLineArgs from 'command-line-args'
|
2
2
|
import commandLineUsage from 'command-line-usage'
|
3
|
-
import { getFinalizedHost } from '../config'
|
3
|
+
import { getAuthConfig, getFinalizedHost } from '../config'
|
4
|
+
import { startServer } from './login-server'
|
5
|
+
import url, { URL } from 'url'
|
6
|
+
import * as crypto from 'crypto'
|
4
7
|
import chalk from 'chalk'
|
5
|
-
import https from 'https'
|
6
|
-
import http from 'http'
|
7
8
|
import { WriteKey } from '../key'
|
9
|
+
import fetch from 'node-fetch'
|
10
|
+
|
11
|
+
const port = 20000
|
8
12
|
|
9
13
|
export function runLogin(argv: string[]) {
|
10
14
|
const optionDefinitions = [
|
@@ -15,23 +19,23 @@ export function runLogin(argv: string[]) {
|
|
15
19
|
description: 'Display this usage guide.',
|
16
20
|
},
|
17
21
|
{
|
18
|
-
name: '
|
22
|
+
name: 'host',
|
23
|
+
description: '(Optional) Override Sentio Host name',
|
19
24
|
type: String,
|
20
|
-
description: '(Required) Your API key',
|
21
25
|
},
|
22
26
|
{
|
23
|
-
name: '
|
24
|
-
description: '(Optional) Override Sentio Host name',
|
27
|
+
name: 'api-key',
|
25
28
|
type: String,
|
29
|
+
description: '(Optional) Your API key',
|
26
30
|
},
|
27
31
|
]
|
28
32
|
const options = commandLineArgs(optionDefinitions, { argv })
|
29
33
|
|
30
|
-
if (options.help
|
34
|
+
if (options.help) {
|
31
35
|
const usage = commandLineUsage([
|
32
36
|
{
|
33
37
|
header: 'Login to Sentio',
|
34
|
-
content: 'sentio login
|
38
|
+
content: 'sentio login',
|
35
39
|
},
|
36
40
|
{
|
37
41
|
header: 'Options',
|
@@ -39,32 +43,59 @@ export function runLogin(argv: string[]) {
|
|
39
43
|
},
|
40
44
|
])
|
41
45
|
console.log(usage)
|
42
|
-
} else {
|
46
|
+
} else if (options['api-key']) {
|
43
47
|
const host = getFinalizedHost(options.host)
|
44
48
|
console.log(chalk.blue('login to ' + host))
|
45
|
-
const
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
path: '/api/v1/processors/check_key',
|
50
|
-
method: 'HEAD',
|
51
|
-
headers: {
|
52
|
-
'api-key': options['api-key'],
|
53
|
-
},
|
54
|
-
}
|
55
|
-
const h = url.protocol == 'https:' ? https : http
|
56
|
-
const req = h.request(reqOptions, (res) => {
|
57
|
-
if (res.statusCode == 200) {
|
58
|
-
WriteKey(host, options['api-key'])
|
49
|
+
const apiKey = options['api-key']
|
50
|
+
checkKey(host, apiKey).then((res) => {
|
51
|
+
if (res.status == 200) {
|
52
|
+
WriteKey(host, apiKey)
|
59
53
|
console.log(chalk.green('login success'))
|
60
54
|
} else {
|
61
|
-
console.error(chalk.red('login failed, code:', res.
|
55
|
+
console.error(chalk.red('login failed, code:', res.status, res.statusText))
|
62
56
|
}
|
63
57
|
})
|
58
|
+
} else {
|
59
|
+
// https://auth0.com/docs/get-started/authentication-and-authorization-flow/call-your-api-using-the-authorization-code-flow-with-pkce
|
60
|
+
const verifier = base64URLEncode(crypto.randomBytes(32))
|
61
|
+
const challenge = base64URLEncode(sha256(verifier))
|
64
62
|
|
65
|
-
|
66
|
-
|
63
|
+
const conf = getAuthConfig(options.host)
|
64
|
+
const authURL = new URL(conf.domain + `/authorize?`)
|
65
|
+
const params = new url.URLSearchParams({
|
66
|
+
response_type: 'code',
|
67
|
+
code_challenge: challenge,
|
68
|
+
code_challenge_method: 'S256',
|
69
|
+
client_id: conf.clientId,
|
70
|
+
redirect_uri: `http://localhost:${port}/callback`,
|
71
|
+
audience: conf.audience,
|
72
|
+
prompt: 'login',
|
73
|
+
})
|
74
|
+
authURL.search = params.toString()
|
75
|
+
console.log('Continue your authorization here: ' + authURL.toString())
|
76
|
+
|
77
|
+
startServer({
|
78
|
+
serverPort: port,
|
79
|
+
sentioHost: options.host,
|
80
|
+
codeVerifier: verifier,
|
67
81
|
})
|
68
|
-
req.end()
|
69
82
|
}
|
70
83
|
}
|
84
|
+
|
85
|
+
function base64URLEncode(str: Buffer) {
|
86
|
+
return str.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
87
|
+
}
|
88
|
+
|
89
|
+
function sha256(str: string) {
|
90
|
+
return crypto.createHash('sha256').update(str).digest()
|
91
|
+
}
|
92
|
+
|
93
|
+
async function checkKey(host: string, apiKey: string) {
|
94
|
+
const checkApiKeyUrl = new URL('/api/v1/processors/check_key', host)
|
95
|
+
return fetch(checkApiKeyUrl, {
|
96
|
+
method: 'HEAD',
|
97
|
+
headers: {
|
98
|
+
'api-key': apiKey,
|
99
|
+
},
|
100
|
+
})
|
101
|
+
}
|
package/src/cli/config.ts
CHANGED
@@ -22,6 +22,35 @@ export function getFinalizedHost(host: string): string {
|
|
22
22
|
return host
|
23
23
|
}
|
24
24
|
|
25
|
+
export function getAuthConfig(host: string): { domain: string; clientId: string; audience: string } {
|
26
|
+
let domain = '',
|
27
|
+
clientId = '',
|
28
|
+
audience = ''
|
29
|
+
switch (host) {
|
30
|
+
case 'local':
|
31
|
+
domain = 'https://sentio-dev.us.auth0.com'
|
32
|
+
clientId = 'qGDisObqQbcPeRA8k02POPZ2Df4KVCna'
|
33
|
+
audience = 'http://localhost:8080/v1'
|
34
|
+
break
|
35
|
+
case '':
|
36
|
+
case undefined:
|
37
|
+
case 'prod':
|
38
|
+
domain = 'https://auth.sentio.xyz'
|
39
|
+
clientId = 'xd80PeuvuZVHpBFh7yEdlSZdtE5mTpGe'
|
40
|
+
audience = 'https://app.sentio.xyz/api/v1'
|
41
|
+
break
|
42
|
+
case 'test':
|
43
|
+
case 'staging':
|
44
|
+
domain = 'https://auth.test.sentio.xyz'
|
45
|
+
clientId = 'qXVvovHaOE37SndxTZJxCKgZjw1axPax'
|
46
|
+
audience = 'https://test.sentio.xyz/api/v1'
|
47
|
+
break
|
48
|
+
default:
|
49
|
+
break
|
50
|
+
}
|
51
|
+
return { domain, clientId, audience }
|
52
|
+
}
|
53
|
+
|
25
54
|
export function finalizeHost(config: SentioProjectConfig) {
|
26
55
|
config.host = getFinalizedHost(config.host)
|
27
56
|
}
|