/
token.ts
85 lines (70 loc) · 2.8 KB
/
token.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import chalk from 'chalk';
import jwt from 'jsonwebtoken';
import type { CommanderStatic } from 'commander';
import { displayError, event, requireFromPackage } from '../utils';
export const defaultExpiry = '30 days';
const parsePayload = (payloadArray: string[] = []) => {
const result = {};
payloadArray.forEach((entry = '') => {
const [key, value] = entry.split('=');
if (key && value) result[key] = value;
});
return result;
};
type TokenOptions = {
expiry?: string;
secret?: string;
expiresIn?: string
payload: string[]
userContext: string[]
};
export const token = async (options: TokenOptions) => {
event('Generate Token');
const CubejsServer = await requireFromPackage('@cubejs-backend/server');
const { expiry = defaultExpiry, secret = CubejsServer.apiSecret() } = options;
if (!secret) {
throw new Error('No app secret found');
}
const extraOptions: Record<string, string> = {};
if (expiry !== '0') {
extraOptions.expiresIn = expiry;
}
const payload = {
...parsePayload(options.payload),
u: parsePayload(options.userContext),
};
console.log('Generating Cube.js JWT token');
console.log('');
console.log(`${chalk.yellow('-----------------------------------------------------------------------------------------')}`);
console.log(` ${chalk.yellow('Use these manually generated tokens in production with caution.')}`);
console.log(` ${chalk.yellow(`Please refer to ${chalk.cyan('https://cube.dev/docs/security')} for production security best practices.`)}`);
console.log(`${chalk.yellow('-----------------------------------------------------------------------------------------')}`);
console.log('');
console.log(`Expires in: ${chalk.green(expiry)}`);
console.log(`Payload: ${chalk.green(JSON.stringify(payload))}`);
console.log('');
const signedToken = jwt.sign(payload, secret, extraOptions);
console.log(`Token: ${chalk.green(signedToken)}`);
await event('Generate Token Success');
return signedToken;
};
export const collect = (val, memo) => [val, ...memo];
export function configureTokenCommand(program: CommanderStatic) {
program
.command('token')
.option('-e, --expiry [expiry]', 'Token expiry. Set to 0 for no expiry')
.option('-s, --secret [secret]', 'Cube.js app secret. Also can be set via environment variable CUBEJS_API_SECRET')
.option('-p, --payload [values]', 'Payload. Example: -p foo=bar', collect, [])
.option('-u, --user-context [values]', 'USER_CONTEXT. Example: -u baz=qux', collect, [])
.description('Create JWT token')
.action(
(options) => token(options)
.catch(e => displayError(e.stack || e))
)
.on('--help', () => {
console.log('');
console.log('Examples:');
console.log('');
console.log(' $ cubejs token -e "1 day" -p foo=bar -p cool=true');
});
}