diff options
| author | LLLL Colonq <llll@colonq> | 2024-11-05 02:58:33 -0500 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2024-11-05 02:58:33 -0500 |
| commit | cf0070ac5a78d8042fa74d407fb9cb65352e2066 (patch) | |
| tree | 85fb5cee6c7533b7ae6de846ed447772d7b67296 /src/Auth.js | |
Initial commit
Diffstat (limited to 'src/Auth.js')
| -rw-r--r-- | src/Auth.js | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/Auth.js b/src/Auth.js new file mode 100644 index 0000000..7254c40 --- /dev/null +++ b/src/Auth.js @@ -0,0 +1,45 @@ +function generateNonce() { + var arr = new Uint8Array(20); + window.crypto.getRandomValues(arr); + return Array.from(arr, b => b.toString(16).padStart(2, "0")).join(""); +} + +export const _startTwitchAuth = (clientID) => (redirectURL) => () => { + const nonce = generateNonce(); + document.cookie = `authnonce=${nonce}; path=/; max-age=3000`; + window.location.href = + `https://id.twitch.tv/oauth2/authorize?response_type=id_token` + + `&client_id=${clientID}` + + `&redirect_uri=${redirectURL}` + + `&scope=openid` + + `&nonce=${nonce}` + + `&claims=${JSON.stringify({id_token: {preferred_username: null}})}` + ; +}; + +function getFragmentQuery() { + let query = new Map(); + const hashQuery = document.location.hash.slice(1).split("&"); + for (let equals of hashQuery) { + const pair = equals.split("="); + query.set(decodeURIComponent(pair[0]), decodeURIComponent(pair[1])); + } + return query; +} + +export const _getToken = (Just) => (Nothing) => (pair) => () => { + const frag = getFragmentQuery(); + const token = frag.get("id_token"); + if (token) { + document.cookie = `id_token=${token}; path=/; SameSite=Strict`; + } + let id_token = null; + let authnonce = null; + for (let c of document.cookie.split("; ")) { + const [k, v] = c.split("="); + if (k === "id_token") id_token = v; + else if (k === "authnonce") authnonce = v; + } + if (id_token && authnonce) return Just(pair(id_token)(authnonce)); + return Nothing; +}; |
