From 17b4ad1e92a142697b43527b8983b942dc80325b Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Sun, 15 Dec 2024 23:36:09 +0530 Subject: [PATCH 1/8] Added logout on token expiry --- src/auth.ts | 12 ++++++++++-- src/cli/validateToken.ts | 11 +++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 5a6e39d..2ffc6e4 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -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 => { @@ -54,8 +55,15 @@ const authToken = async (config: Config): Promise => { } if (expiresIn(token) < config.renewTime) { - // Token expires in < renewTime - token = await api.refresh(); + try { + // Attempt to refresh token + token = await api.refresh(); + } catch (err) { + // If refresh fails, force logout + await logout(); + info('Session expired. Please login again with email/password.'); + process.exit(1); + } } return token; diff --git a/src/cli/validateToken.ts b/src/cli/validateToken.ts index 122ffca..3ca107d 100644 --- a/src/cli/validateToken.ts +++ b/src/cli/validateToken.ts @@ -1,6 +1,7 @@ import { API as APIInterface } from '@metacall/protocol/protocol'; import { unlink } from 'fs/promises'; import { configFilePath, save } from '../config'; +import { logout } from '../logout'; import { exists } from '../utils'; import args from './args'; import { error, info } from './messages'; @@ -9,8 +10,14 @@ const handleValidateToken = async (api: APIInterface): Promise => { const validToken = await api.validate(); if (!validToken) { - const token = await api.refresh(); - await save({ token }); + try { + const token = await api.refresh(); + await save({ token }); + } catch (err) { + await logout(); + info('Token expired. Please login again.'); + process.exit(1); + } } }; From 29b1b743320ec5b7cb2b247e4334b2a2ad2631c1 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Wed, 18 Dec 2024 09:32:29 +0530 Subject: [PATCH 2/8] reverted old change --- src/auth.ts | 12 ++---------- src/cli/validateToken.ts | 11 ++--------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 2ffc6e4..5a6e39d 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -16,7 +16,6 @@ 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 => { @@ -55,15 +54,8 @@ const authToken = async (config: Config): Promise => { } if (expiresIn(token) < config.renewTime) { - try { - // Attempt to refresh token - token = await api.refresh(); - } catch (err) { - // If refresh fails, force logout - await logout(); - info('Session expired. Please login again with email/password.'); - process.exit(1); - } + // Token expires in < renewTime + token = await api.refresh(); } return token; diff --git a/src/cli/validateToken.ts b/src/cli/validateToken.ts index 3ca107d..122ffca 100644 --- a/src/cli/validateToken.ts +++ b/src/cli/validateToken.ts @@ -1,7 +1,6 @@ import { API as APIInterface } from '@metacall/protocol/protocol'; import { unlink } from 'fs/promises'; import { configFilePath, save } from '../config'; -import { logout } from '../logout'; import { exists } from '../utils'; import args from './args'; import { error, info } from './messages'; @@ -10,14 +9,8 @@ const handleValidateToken = async (api: APIInterface): Promise => { const validToken = await api.validate(); if (!validToken) { - try { - const token = await api.refresh(); - await save({ token }); - } catch (err) { - await logout(); - info('Token expired. Please login again.'); - process.exit(1); - } + const token = await api.refresh(); + await save({ token }); } }; From 4e6aed7016861f80250cac0718f3a885b8d04519 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Wed, 18 Dec 2024 16:36:49 +0530 Subject: [PATCH 3/8] logout on token expiry --- src/cli/validateToken.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/cli/validateToken.ts b/src/cli/validateToken.ts index 122ffca..08178a0 100644 --- a/src/cli/validateToken.ts +++ b/src/cli/validateToken.ts @@ -1,6 +1,7 @@ import { API as APIInterface } from '@metacall/protocol/protocol'; import { unlink } from 'fs/promises'; -import { configFilePath, save } from '../config'; +import { auth } from '../auth'; +import { configFilePath, defaultPath, load, save } from '../config'; import { exists } from '../utils'; import args from './args'; import { error, info } from './messages'; @@ -32,11 +33,18 @@ const validateToken = async (api: APIInterface): Promise => { (await exists(configFile)) && (await unlink(configFile)); - info('Try to login again!'); + info('Token expired, initiating token-based login...'); - return error( - `Token validation failed, potential causes include:\n\t1) The JWT may be mistranslated (Invalid Signature).\n\t2) JWT might have expired.` - ); + try { + const config = await load(defaultPath); + + const newToken = await auth(config); + // Save the new token + await save({ token: newToken }); + return; + } catch (loginErr) { + return error('Token validation failed. Please try again.'); + } } }; From b5567d4c652da9f5657aa47dfb8808e986c57da7 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Thu, 19 Dec 2024 00:17:51 +0530 Subject: [PATCH 4/8] reverted my change --- src/cli/validateToken.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/cli/validateToken.ts b/src/cli/validateToken.ts index 08178a0..122ffca 100644 --- a/src/cli/validateToken.ts +++ b/src/cli/validateToken.ts @@ -1,7 +1,6 @@ import { API as APIInterface } from '@metacall/protocol/protocol'; import { unlink } from 'fs/promises'; -import { auth } from '../auth'; -import { configFilePath, defaultPath, load, save } from '../config'; +import { configFilePath, save } from '../config'; import { exists } from '../utils'; import args from './args'; import { error, info } from './messages'; @@ -33,18 +32,11 @@ const validateToken = async (api: APIInterface): Promise => { (await exists(configFile)) && (await unlink(configFile)); - info('Token expired, initiating token-based login...'); + info('Try to login again!'); - try { - const config = await load(defaultPath); - - const newToken = await auth(config); - // Save the new token - await save({ token: newToken }); - return; - } catch (loginErr) { - return error('Token validation failed. Please try again.'); - } + return error( + `Token validation failed, potential causes include:\n\t1) The JWT may be mistranslated (Invalid Signature).\n\t2) JWT might have expired.` + ); } }; From 42ae2382e0ecdc4655dd477756a4ea2e10ce75e4 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Sun, 22 Dec 2024 01:30:07 +0530 Subject: [PATCH 5/8] fixing test in PRs --- .github/workflows/ci.yml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc39ca6..d919e85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI on: - pull_request: + pull_request_target: push: branches: - master @@ -11,8 +11,10 @@ jobs: ci: runs-on: ubuntu-latest steps: - - name: Checkout + - name: Checkout Code uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref || github.ref }} - name: Setup NodeJS uses: actions/setup-node@v4 @@ -20,25 +22,27 @@ jobs: node-version: '16' registry-url: https://registry.npmjs.org - - name: Installing Dependencies + - name: Install Dependencies run: npm i - - name: Lint + - name: Lint Code run: npm run lint - - name: Build + - name: Build Project run: npm run build - - name: Run Tests + - name: Setup Environment Variables run: | touch .env - echo 'METACALL_AUTH_EMAIL="${{ secrets.METACALL_AUTH_EMAIL }}"' >> .env - echo 'METACALL_AUTH_PASSWORD="${{ secrets.METACALL_AUTH_PASSWORD }}"' >> .env - npm run coverage + echo "METACALL_AUTH_EMAIL=${{ secrets.METACALL_AUTH_EMAIL }}" >> .env + echo "METACALL_AUTH_PASSWORD=${{ secrets.METACALL_AUTH_PASSWORD }}" >> .env + + - name: Run Tests + run: npm run coverage - - name: Publish + - name: Publish to NPM uses: JS-DevTools/npm-publish@v1 if: startsWith(github.ref, 'refs/tags/') with: access: 'public' - token: '${{ secrets.NPM_AUTH_TOKEN }}' + token: ${{ secrets.NPM_AUTH_TOKEN }} From 3fe2635ebeeb1979c2d0e02ae11aa480ececc9cd Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Sun, 22 Dec 2024 01:34:57 +0530 Subject: [PATCH 6/8] reverting the ci changes --- .github/workflows/ci.yml | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d919e85..202e33f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI on: - pull_request_target: + pull_request: push: branches: - master @@ -11,38 +11,34 @@ jobs: ci: runs-on: ubuntu-latest steps: - - name: Checkout Code + - name: Checkout uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.ref || github.ref }} - name: Setup NodeJS uses: actions/setup-node@v4 with: - node-version: '16' + node-version: '20' registry-url: https://registry.npmjs.org - - name: Install Dependencies + - name: Installing Dependencies run: npm i - - name: Lint Code + - name: Lint run: npm run lint - - name: Build Project + - name: Build run: npm run build - - name: Setup Environment Variables + - name: Run Tests run: | touch .env - echo "METACALL_AUTH_EMAIL=${{ secrets.METACALL_AUTH_EMAIL }}" >> .env - echo "METACALL_AUTH_PASSWORD=${{ secrets.METACALL_AUTH_PASSWORD }}" >> .env - - - name: Run Tests - run: npm run coverage + echo 'METACALL_AUTH_EMAIL="${{ secrets.METACALL_AUTH_EMAIL }}"' >> .env + echo 'METACALL_AUTH_PASSWORD="${{ secrets.METACALL_AUTH_PASSWORD }}"' >> .env + npm run coverage - - name: Publish to NPM + - name: Publish uses: JS-DevTools/npm-publish@v1 if: startsWith(github.ref, 'refs/tags/') with: access: 'public' - token: ${{ secrets.NPM_AUTH_TOKEN }} + token: '${{ secrets.NPM_AUTH_TOKEN }}' From 805d064240982c6baab426679a3222320bbe9d56 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Fri, 24 Jan 2025 02:04:23 +0530 Subject: [PATCH 7/8] Auto Logout when token expires --- src/auth.ts | 21 +++++++++++++++++---- src/cli/selection.ts | 9 +++++++-- src/cli/validateToken.ts | 28 ++++++++++++++++++++++------ src/index.ts | 2 +- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 5a6e39d..862012b 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -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 => { @@ -54,8 +55,17 @@ const authToken = async (config: Config): Promise => { } 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; @@ -169,7 +179,10 @@ const authSignup = async (config: Config): Promise => { return process.exit(ErrorCode.Ok); }; -const authSelection = async (config: Config): Promise => { +export const authSelection = async ( + config: Config, + isReLogin = false +): Promise => { const token = await (async () => { if (args['email'] || args['password']) { return await authLogin(config); @@ -180,7 +193,7 @@ const authSelection = async (config: Config): Promise => { { '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))]( diff --git a/src/cli/selection.ts b/src/cli/selection.ts index 03142fd..94a8a31 100644 --- a/src/cli/selection.ts +++ b/src/cli/selection.ts @@ -6,12 +6,17 @@ import { import { Plans } from '@metacall/protocol/plan'; import { prompt } from 'inquirer'; -export const loginSelection = (methods: string[]): Promise => +export const loginSelection = ( + methods: string[], + isReLogin = false +): Promise => 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); diff --git a/src/cli/validateToken.ts b/src/cli/validateToken.ts index 122ffca..2eaa86d 100644 --- a/src/cli/validateToken.ts +++ b/src/cli/validateToken.ts @@ -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 => { +const handleValidateToken = async ( + api: APIInterface, + config: Config +): Promise => { 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 => { +const validateToken = async ( + api: APIInterface, + config: Config +): Promise => { try { - await handleValidateToken(api); + await handleValidateToken(api, config); } catch (err) { if (args['dev']) { info( diff --git a/src/index.ts b/src/index.ts index 3ab86b4..d172c51 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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); From bf5f322149bd821e2011de24fc4879b8b84eae41 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Sun, 9 Feb 2025 00:53:06 +0530 Subject: [PATCH 8/8] Added nohup --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc5b9e8..baad769 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: - name: Run Tests (local) run: | export TEST_DEPLOY_LOCAL="true" - metacall-faas & + nohup metacall-faas 2>&1 & sleep 10 mv .env.example .env npm run coverage