-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathrunRoutes.tsx
90 lines (72 loc) · 2.27 KB
/
runRoutes.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import GoTrue, { User } from 'gotrue-js';
import { TokenParam, defaultParam } from './token';
/**
* This code runs on every rerender so keep it light
* keep checking the current route and do logic based on the route
* as dictated by netlify identity's communication with us via hashes
*/
const routes = /(confirmation|invite|recovery|email_change|access)_token=([^&]+)/;
const errorRoute = /error=access_denied&error_description=403/;
const reduceHashToKeyValue = (hash: string): { [key: string]: string } =>
hash.split('&').reduce((carry, pair) => {
const [key, value] = pair.split('=');
return { ...carry, [key]: value };
}, {});
const hashReplace = /^#\/?/;
export function runRoutes(
gotrue: GoTrue,
setUser: (value: User) => User | undefined,
remember = true
): TokenParam {
// early terminate if no hash
// also accounts for document.cookie further down
if (!document?.location?.hash) {
return defaultParam;
}
const hash = document.location.hash.replace(hashReplace, '');
try {
history.pushState(
'',
document.title,
window.location.pathname + window.location.search
);
} catch (_) {
window.location.href.substr(0, window.location.href.indexOf('#'));
}
// earliest possible bail on any match
if (hash.match(errorRoute)) {
return {
...defaultParam,
error: 'access_denied',
status: 403,
};
}
const matchesActionHashes = hash.match(routes);
if (matchesActionHashes) {
const params = reduceHashToKeyValue(hash);
if (params.confirmation_token) {
gotrue
.confirm(params.confirmation_token, remember)
.then(setUser)
.catch(console.error);
// dont notify dev as this package does not export its own method for this
return defaultParam;
}
if (params.access_token) {
document.cookie = `nf_jwt=${params.access_token}`;
gotrue
.createUser(params, remember)
.then(setUser)
.catch(console.error);
// also dont notify dev here for the same reasons as above
return defaultParam;
}
// pass responsibility to dev in all other cases
return {
...defaultParam,
type: matchesActionHashes[1] as TokenParam['type'],
token: matchesActionHashes[2],
};
}
return defaultParam;
}