From 7dd426241200b936cc231c553ed7b2b95e95022c Mon Sep 17 00:00:00 2001 From: Kyle Johnson Date: Tue, 1 Oct 2024 11:27:14 +0100 Subject: [PATCH] feat: auth jwt cookie frontend (#4669) --- frontend/.eslintrc.js | 1 + frontend/common/data/base/_data.js | 1 + frontend/common/service.ts | 3 ++- frontend/common/stores/account-store.js | 19 ++++++++++++------- frontend/global.d.ts | 1 + frontend/web/main.js | 2 +- frontend/webpack/plugins.js | 3 ++- 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index b8b72785806d..0990eb0e9165 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -98,6 +98,7 @@ module.exports = { 'toast': true, 'window': true, 'zE': true, + 'COOKIE_AUTH_ENABLED': true, }, 'ignorePatterns': ['server/index.js', 'next.config.js', 'babel.config.js'], 'parser': '@typescript-eslint/parser', diff --git a/frontend/common/data/base/_data.js b/frontend/common/data/base/_data.js index 17c7e529d13a..a9ac2845461e 100644 --- a/frontend/common/data/base/_data.js +++ b/frontend/common/data/base/_data.js @@ -9,6 +9,7 @@ const getQueryString = (params) => { module.exports = { _request(method, _url, data, headers = {}) { const options = { + credentials: COOKIE_AUTH_ENABLED ? 'include' : undefined, headers: { 'Accept': 'application/json', ...headers, diff --git a/frontend/common/service.ts b/frontend/common/service.ts index 725d930f1938..e41dc4967cda 100644 --- a/frontend/common/service.ts +++ b/frontend/common/service.ts @@ -16,6 +16,7 @@ export const baseApiOptions = (queryArgs?: Partial) => { | 'extractRehydrationInfo' > = { baseQuery: fetchBaseQuery({ + credentials: COOKIE_AUTH_ENABLED ? 'include' : 'omit', // 'include' for cookies, 'omit' if not baseUrl: Project.api, prepareHeaders: async (headers, { endpoint, getState }) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -29,7 +30,7 @@ export const baseApiOptions = (queryArgs?: Partial) => { ) { try { const token = _data.token - if (token) { + if (token && !COOKIE_AUTH_ENABLED) { headers.set('Authorization', `Token ${token}`) } } catch (e) {} diff --git a/frontend/common/stores/account-store.js b/frontend/common/stores/account-store.js index bd847484fcd9..5d71ec4d5bbe 100644 --- a/frontend/common/stores/account-store.js +++ b/frontend/common/stores/account-store.js @@ -241,12 +241,12 @@ const controller = { .post(`${Project.api}auth/users/`, { email, first_name, + invite_hash: API.getInvite() || undefined, last_name, marketing_consent_given, password, referrer: API.getReferrer() || '', sign_up_type: API.getInviteType(), - invite_hash: API.getInvite() || undefined, }) .then((res) => { data.setToken(res.key) @@ -328,12 +328,17 @@ const controller = { } else if (!user) { store.ephemeral_token = null AsyncStorage.clear() - API.setCookie('t', '') - data.setToken(null) - API.reset().finally(() => { - store.model = user - store.organisation = null - store.trigger('logout') + if (!data.token) { + return + } + data.post(`${Project.api}auth/logout/`, {}).finally(() => { + API.setCookie('t', '') + data.setToken(null) + API.reset().finally(() => { + store.model = user + store.organisation = null + store.trigger('logout') + }) }) } }, diff --git a/frontend/global.d.ts b/frontend/global.d.ts index 9ca8cbfeb70d..96dac0ef12a9 100644 --- a/frontend/global.d.ts +++ b/frontend/global.d.ts @@ -13,6 +13,7 @@ import { TooltipProps } from './web/components/Tooltip' export declare const openModal: (name?: string) => Promise declare global { + const COOKIE_AUTH_ENABLED: boolean const openModal: ( title: ReactNode, body?: ReactNode, diff --git a/frontend/web/main.js b/frontend/web/main.js index c4d140bc6ff2..f773539c717a 100644 --- a/frontend/web/main.js +++ b/frontend/web/main.js @@ -26,7 +26,7 @@ if (params.token) { } // Render the React application to the DOM -const res = API.getCookie('t') +const res = COOKIE_AUTH_ENABLED ? 'true' : API.getCookie('t') const event = API.getEvent() if (event) { diff --git a/frontend/webpack/plugins.js b/frontend/webpack/plugins.js index e19630316da5..d7a84e070274 100644 --- a/frontend/webpack/plugins.js +++ b/frontend/webpack/plugins.js @@ -7,7 +7,8 @@ module.exports = [ new webpack.DefinePlugin({ E2E: process.env.E2E, SENTRY_RELEASE_VERSION: true, - DYNATRACE_URL: !!process.env.DYNATRACE_URL && JSON.stringify(process.env.DYNATRACE_URL) + DYNATRACE_URL: !!process.env.DYNATRACE_URL && JSON.stringify(process.env.DYNATRACE_URL), + COOKIE_AUTH_ENABLED: !!process.env.COOKIE_AUTH_ENABLED, }), // // Fixes warning in moment-with-locales.min.js // // Module not found: Error: Can't resolve './locale' in ...