Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added logout on token expiry #171

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { error, info, warn } from './cli/messages';
import { loginSelection } from './cli/selection';
import { Config, save } from './config';
import { ErrorCode } from './deploy';
import { logout } from './logout';
import { forever } from './utils';

const authToken = async (config: Config): Promise<string> => {
Expand Down Expand Up @@ -54,8 +55,17 @@ const authToken = async (config: Config): Promise<string> => {
}

if (expiresIn(token) < config.renewTime) {
// Token expires in < renewTime
token = await api.refresh();
try {
// Attempt to refresh token
token = await api.refresh();
token && (await save({ token }));
} catch (err) {
await logout();
info('Token expired. Please login again.');
// Pass isReLogin as true
const newToken = await authSelection(config, true);
await save({ token: newToken });
}
}

return token;
Expand Down Expand Up @@ -169,7 +179,10 @@ const authSignup = async (config: Config): Promise<string> => {
return process.exit(ErrorCode.Ok);
};

const authSelection = async (config: Config): Promise<string> => {
export const authSelection = async (
config: Config,
isReLogin = false
): Promise<string> => {
const token = await (async () => {
if (args['email'] || args['password']) {
return await authLogin(config);
Expand All @@ -180,7 +193,7 @@ const authSelection = async (config: Config): Promise<string> => {
{
'Login by token': authToken,
'Login by email and password': authLogin,
'New user, sign up': authSignup
...(isReLogin ? {} : { 'New user, sign up': authSignup })
};

return await methods[await loginSelection(Object.keys(methods))](
Expand Down
9 changes: 7 additions & 2 deletions src/cli/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import {
import { Plans } from '@metacall/protocol/plan';
import { prompt } from 'inquirer';

export const loginSelection = (methods: string[]): Promise<string> =>
export const loginSelection = (
methods: string[],
isReLogin = false
): Promise<string> =>
prompt<{ method: string }>([
{
type: 'list',
name: 'method',
message: 'Select the login method',
message: isReLogin
? 'Token expired. Select login method'
: 'Select the login method',
choices: methods
}
]).then((res: { method: string }) => res.method);
Expand Down
28 changes: 22 additions & 6 deletions src/cli/validateToken.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
import { API as APIInterface } from '@metacall/protocol/protocol';
import { unlink } from 'fs/promises';
import { configFilePath, save } from '../config';
import { authSelection } from '../auth';
import { Config, configFilePath, save } from '../config';
import { logout } from '../logout';
import { exists } from '../utils';
import args from './args';
import { error, info } from './messages';

const handleValidateToken = async (api: APIInterface): Promise<void> => {
const handleValidateToken = async (
api: APIInterface,
config: Config
): Promise<void> => {
const validToken = await api.validate();

if (!validToken) {
const token = await api.refresh();
await save({ token });
try {
const token = await api.refresh();
token && (await save({ token }));
} catch (err) {
await logout();
info('Token expired. Please login again.');
// Pass isReLogin as true
const newToken = await authSelection(config, true);
await save({ token: newToken });
}
}
};

const validateToken = async (api: APIInterface): Promise<void> => {
const validateToken = async (
api: APIInterface,
config: Config
): Promise<void> => {
try {
await handleValidateToken(api);
await handleValidateToken(api, config);
} catch (err) {
if (args['dev']) {
info(
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void (async () => {
args['dev'] ? config.devURL : config.baseURL
);

await validateToken(api);
await validateToken(api, config);

if (args['listPlans']) return await listPlans(api);

Expand Down
Loading