UNPKG

3.67 kBJavaScriptView Raw
1'use strict';
2
3const Promise = require('bluebird');
4const httpRequest = require('./httpRequest');
5const config = require('./config');
6const ArgError = require('../errors').ArgError;
7const logger = require('./logger').getLogger('testim-custom-token');
8const localRunnerCache = require('./runnerFileCache');
9
10let _serverToken;
11let _serverTokenExp;
12let _refreshToken;
13let _ngrokToken;
14
15let _projectId = null;
16let _token = null;
17
18const FIVE_MIN_IN_MS = 5 * 60 * 1000;
19
20
21async function init(projectId, token) {
22 _projectId = projectId;
23 _token = token;
24 const tokenValue = await generateToken();
25 return tokenValue;
26}
27
28
29function initFromData(authData, projectId, token) {
30 _serverToken = authData.token;
31 _projectId = projectId;
32 _token = token;
33 _serverTokenExp = getTokenExp(_serverToken);
34 _refreshToken = authData.refreshToken;
35 _ngrokToken = authData.ngrokToken;
36}
37
38function getTokenV3(projectId = _projectId, token = _token) {
39 return localRunnerCache.memoize(() => {
40 logger.info('request to get cli token from server');
41 return httpRequest.post({
42 url: `${config.SERVICES_HOST}/auth/token`,
43 body: { projectId, token },
44 });
45 }, 'getTokenV3', FIVE_MIN_IN_MS * 10, { projectId, token })();
46}
47
48async function refreshToken() {
49 logger.info('request to refresh JWT cli token from server');
50 const customToken = await httpRequest.post({
51 url: `${config.SERVICES_HOST}/auth/refreshToken`,
52 body: { token: _serverToken, refreshToken: _refreshToken },
53 });
54 _serverToken = customToken.token;
55 _serverTokenExp = getTokenExp(_serverToken);
56 return _serverToken;
57}
58
59function generateToken() {
60 return getTokenV3()
61 .then(customToken => {
62 logger.info('successfully get cli token from server');
63 _serverToken = customToken.token;
64 _serverTokenExp = getTokenExp(_serverToken);
65 _refreshToken = customToken.refreshToken;
66 _ngrokToken = customToken.ngrokToken;
67 return _serverToken;
68 })
69 .catch(error => error.message.includes('Unauthorized'), () => {
70 throw new ArgError(
71 'Error trying to retrieve CLI token. ' +
72 'Your CLI token and project might not match. ' +
73 'Please make sure to pass `--project` and `--token` that' +
74 ' match to each other or make sure they match in your ~/.testim file.');
75 })
76 .catch(error => {
77 logger.error(`While trying to retrieve CLI token. caught error: ${error}`, { projectId: _projectId });
78 throw new ArgError(`While trying to retrieve CLI token, caught error: ${error}`);
79 });
80}
81
82function getTokenExp(token) {
83 const jwtLib = require('jsonwebtoken');
84 const jwt = jwtLib.decode(token);
85 return jwt.exp * 1000;
86}
87
88function getCustomTokenV3() {
89 if (!_serverTokenExp) {
90 return generateToken();
91 }
92 if (_serverTokenExp < (Date.now() + FIVE_MIN_IN_MS)) {
93 return refreshToken().catch(err => {
94 logger.error('failed to refresh token, executing fallback', err);
95 return generateToken();
96 });
97 }
98 return Promise.resolve(_serverToken);
99}
100
101function getRefreshToken() {
102 return _refreshToken;
103}
104
105function getTokenV3UserData() {
106 if (_serverToken) {
107 const jwtLib = require('jsonwebtoken');
108 const data = jwtLib.decode(_serverToken);
109 return { uid: data.id, ngrokToken: _ngrokToken };
110 }
111 return {};
112}
113
114module.exports = {
115 init: Promise.method(init),
116 initFromData,
117 getCustomTokenV3,
118 getTokenV3UserData,
119 getRefreshToken,
120};