diff --git a/assets/src/js/app/auth.js b/assets/src/js/app/auth.js index dbfa355..399485a 100644 --- a/assets/src/js/app/auth.js +++ b/assets/src/js/app/auth.js @@ -1,15 +1,25 @@ -import {init} from '../lib/supertokens'; -try { - const res = await init(); -} catch (err) { - console.log(err); -} +import {init, refresh} from '../lib/supertokens'; const av = (await import('../lib/asyncView')).initAsyncView; + av(document.querySelector('nav'), 'index', async function() { const self = this; window.addEventListener('auth', function() { - self.load(); + self.reload(); }, { once: true }); }); +try { + await init(window._CSRF); +} catch (err) { + console.log(err); +} +if (window._sessionExpired) { + try { + await refresh(window._CSRF); + window.dispatchEvent(new CustomEvent('auth')); + } catch (err) { + console.log(err); + } +} + export {} diff --git a/assets/src/js/app/auth/login.js b/assets/src/js/app/auth/login.js index 3eea9d5..019f0dd 100644 --- a/assets/src/js/app/auth/login.js +++ b/assets/src/js/app/auth/login.js @@ -11,7 +11,7 @@ window.submitLoginForm = function(target, e) { initCloseable(closeable); } try { - const resp = await supertokens.sendMagicLink(data); + const resp = await supertokens.sendMagicLink(data, window._CSRF); pl.done('login'); pl.finish('magic link sent to ' + data.email); } catch (err) { diff --git a/assets/src/js/app/auth/logout.js b/assets/src/js/app/auth/logout.js index 1a6a5c6..7586f35 100644 --- a/assets/src/js/app/auth/logout.js +++ b/assets/src/js/app/auth/logout.js @@ -7,7 +7,7 @@ av(target, 'auth/logout', async function() { pl.inProgress('logging out', 'logout' ); const supertokens = (await import('../../lib/supertokens')); try { - await supertokens.logout(); + await supertokens.logout(window._CSRF); pl.done('logout'); pl.finish('logout successful'); window.dispatchEvent(new CustomEvent('auth')); diff --git a/assets/src/js/app/auth/verify.js b/assets/src/js/app/auth/verify.js index 2d37c17..bfa0b92 100644 --- a/assets/src/js/app/auth/verify.js +++ b/assets/src/js/app/auth/verify.js @@ -7,7 +7,7 @@ av(target, 'auth/verify', async function() { pl.inProgress('checking magic link', 'verify'); const supertokens = (await import('../../lib/supertokens')); try { - const res = await supertokens.handleMagicLinkClicked(); + const res = await supertokens.handleMagicLinkClicked(window._CSRF); if (res.status === 'OK') { pl.done('verify'); pl.finish('login successful'); diff --git a/assets/src/js/lib/async.js b/assets/src/js/lib/async.js index 87b76c6..dea760c 100644 --- a/assets/src/js/lib/async.js +++ b/assets/src/js/lib/async.js @@ -32,7 +32,7 @@ async function asyncFetch(url, targetSelector, fetchParams, params) { loadAsyncView(target, text, template, layout); return res; } -function async(selector, params = {}, scope = null) { +async function async(selector, params = {}, scope = null) { if (!scope) { scope = document; window.addEventListener('popstate', async function(e) { @@ -51,10 +51,15 @@ function async(selector, params = {}, scope = null) { } const els = scope.querySelectorAll(selector); for (const el of els) { - el.load = function() { + el.reload = function() { let {url, fetchParams} = params.fetchParams.call(el); return asyncFetch.call(el, url, el, fetchParams, params); } + // In case if reload was already invoked + if (el.reloadResolve) { + const res = await el.reload(); + el.reloadResolve(res); + } if (!el.getAttribute('async-target')) continue; el.addEventListener(params.event, async function(e) { e.preventDefault(); diff --git a/assets/src/js/lib/asyncView.js b/assets/src/js/lib/asyncView.js index 93d74be..b5382fd 100644 --- a/assets/src/js/lib/asyncView.js +++ b/assets/src/js/lib/asyncView.js @@ -11,6 +11,14 @@ export function initAsyncView(target, name, init, destroy) { } target.classList.add('async-view'); target.classList.add(`async-view-${name}`); + // In case if async binding has not been invoked + if (!target.reload) { + target.reload = function() { + return new Promise(function(resolve, _) { + target.reloadResolve = resolve; + }) + } + } init.call(target); } window.addEventListener(`async:${name}`, onLoad); diff --git a/assets/src/js/lib/supertokens.js b/assets/src/js/lib/supertokens.js index b54bc1d..7a89c10 100644 --- a/assets/src/js/lib/supertokens.js +++ b/assets/src/js/lib/supertokens.js @@ -2,56 +2,63 @@ import SuperTokens from 'supertokens-web-js'; import Session from 'supertokens-web-js/recipe/session'; import Passwordless, { createCode, consumeCode, signOut } from "supertokens-web-js/recipe/passwordless"; -function preAPIHook(context) { - let requestInit = context.requestInit; - let url = context.url; - let headers = { - ...requestInit.headers, - 'X-CSRF-TOKEN': window._CSRF, - }; - requestInit = { - ...requestInit, - headers, +function preAPIHook(csrf) { + return function(context) { + let requestInit = context.requestInit; + let url = context.url; + let headers = { + ...requestInit.headers, + 'X-CSRF-TOKEN': csrf, + }; + requestInit = { + ...requestInit, + headers, + } + return { + requestInit, url + }; } - return { - requestInit, url - }; } -export async function sendMagicLink({email}) { - initSuperTokens(); +export async function sendMagicLink({email}, csrf) { + initSuperTokens(csrf); return await createCode({ email, options: { - preAPIHook, + preAPIHook: preAPIHook(csrf), }, }); } -export async function handleMagicLinkClicked() { - initSuperTokens(); +export async function handleMagicLinkClicked(csrf) { + initSuperTokens(csrf); return await consumeCode({ options: { - preAPIHook, + preAPIHook: preAPIHook(csrf), }, }); } -export async function logout() { - initSuperTokens(); +export async function logout(csrf) { + initSuperTokens(csrf); return await signOut({ options: { - preAPIHook, + preAPIHook: preAPIHook(csrf), }, }); } -export async function init() { - initSuperTokens(); +export function refresh(csrf) { + initSuperTokens(csrf); + return Session.attemptRefreshingSession(); +} + +export async function init(csrf) { + initSuperTokens(csrf); } let inited = false; -async function initSuperTokens() { +async function initSuperTokens(csrf) { if (inited) { return; } @@ -64,14 +71,10 @@ async function initSuperTokens() { }, recipeList: [ Session.init({ - preAPIHook, + preAPIHook: preAPIHook(csrf), }), Passwordless.init(), ], }); - if (window._sessionExpired) { - if (await Session.attemptRefreshingSession()) { - window.dispatchEvent(new CustomEvent('auth')); - } - } + }