Skip to content

Commit c775f09

Browse files
committed
Make sure logging in's side-effects are reflected across multiple tabs
1 parent 3bc71e3 commit c775f09

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

templates/Foobara/Auth/LoginCommand.ts.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default class LoginCommand<Inputs, Result, Error extends FoobaraError<any
77
extends RemoteCommand<Inputs, Result, Error> {
88
async _handleResponse (response: Response): Promise<Outcome<Result, Error>> {
99
if (response.ok) {
10-
const accessToken: string | null = response.headers.get('X-Access-Token')
10+
const accessToken: string | null = response.headers.get('x-access-token')
1111

1212
if (accessToken != null) {
1313
handleLogin(this.urlBase, accessToken)

templates/Foobara/Auth/utils/accessTokens.ts.erb

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type Query from '../../../base/Query'
22
import type RemoteCommand from '../../../base/RemoteCommand'
33
import { forEachQuery } from '../../../base/QueryCache'
44

5+
// TODO: Why is this in here? It seems general-purpose not auth-specific
56
function dirtyAllQueries () {
67
forEachQuery((query: Query<RemoteCommand<any, any, any>>) => {
78
query.setDirty()
@@ -10,29 +11,49 @@ function dirtyAllQueries () {
1011

1112
const accessTokens = new Map<string, string>()
1213

14+
interface AuthMessage {
15+
type: 'login' | 'logout'
16+
baseUrl: string
17+
}
18+
19+
const login = (baseUrl: string, accessToken: string): void => {
20+
accessTokens.set(baseUrl, accessToken)
21+
dirtyAllQueries()
22+
}
23+
1324
const logout = (urlBase: string): void => {
1425
accessTokens.delete(urlBase)
1526
dirtyAllQueries()
1627
}
28+
29+
// These functions gets overridden with a form that broadcasts the event if BroadcastChannel is available
30+
let handleLogin: (baseUrl: string, accessToken: string) => void = login
1731
let handleLogout: (baseUrl: string) => void = logout
1832

1933
const tokenForUrl = (baseUrl: string): string | undefined => accessTokens.get(baseUrl)
20-
const handleLogin: (baseUrl: string, accessToken: string) => void = (baseUrl, accessToken) => {
21-
accessTokens.set(baseUrl, accessToken)
22-
dirtyAllQueries()
23-
}
2434

2535
if (typeof BroadcastChannel !== 'undefined') {
2636
const logoutChannel = new BroadcastChannel('foobara-auth-events')
2737

28-
logoutChannel.addEventListener('message', (event: MessageEvent<string>) => {
29-
accessTokens.delete(event.data)
30-
deleteAllQueries()
38+
logoutChannel.addEventListener('message', (event: MessageEvent<AuthMessage>) => {
39+
const { type, baseUrl } = event.data
40+
41+
if (type === 'login') {
42+
dirtyAllQueries()
43+
} else if (type === 'logout') {
44+
logout(baseUrl)
45+
} else {
46+
throw new Error(`Unknown auth message type: ${JSON.stringify(type)}`)
47+
}
3148
})
3249

3350
handleLogout = (baseUrl: string) => {
3451
logout(baseUrl)
35-
logoutChannel.postMessage(baseUrl)
52+
logoutChannel.postMessage({ baseUrl, type: 'logout' })
53+
}
54+
handleLogin = (baseUrl: string, accessToken: string) => {
55+
login(baseUrl, accessToken)
56+
logoutChannel.postMessage({ baseUrl, type: 'login' })
3657
}
3758
}
3859

0 commit comments

Comments
 (0)