{ "version": 3, "sources": ["../javascripts/actions/auth.ts", "../javascripts/utils/auth.ts", "../../../node_modules/jwt-decode/build/esm/index.js"], "sourcesContent": ["\uFEFFimport type { Dispatch as ReduxDispatch } from '@reduxjs/toolkit';\n\nimport type { AccessToken } from '../@types/AccessToken';\nimport type { BaseAction } from '../@types/actions';\nimport type { RootState } from '../reducers';\n\nimport type { ProfileFull } from '../@types/Profile';\nimport * as http from '../Http';\nimport {\n buildAuthorizedGetRequest,\n buildAuthorizedPutRequest,\n buildGetRequest,\n} from '../Http/requestTemplates';\nimport requestCache from '../utils/request-cache';\n\nconst REQ_ACCESS_TKN = 'REQ/ACCESS_TKN';\nexport const RCV_ACCESS_TKN = 'RCV/ACCESS_TKN';\ntype REQ_ACCESS_TKN_TYPE = BaseAction;\ntype RCV_ACCESS_TKN_TYPE = BaseAction & {\n response: AccessToken;\n};\nexport const REQ_PROFILE = 'REQ/PROFILE';\nexport const RCV_PROFILE = 'RCV/PROFILE';\ntype REQ_PROFILE_TYPE = BaseAction;\ntype RCV_PROFILE_TYPE = BaseAction & {\n response: ProfileFull;\n};\nexport const REQ_UPDATE_PROFILE = 'REQ/UPDATE_PROFILE';\nexport const RCV_UPDATE_PROFILE = 'RCV/UPDATE_PROFILE';\ntype REQ_UPDATE_PROFILE_TYPE = BaseAction;\ntype RCV_UPDATE_PROFILE_TYPE = BaseAction & {\n response: ProfileFull;\n};\n\nexport const REQUEST_FAILED = 'PROFILE/REQUEST_FAILED';\ntype REQUEST_FAILED_TYPE = BaseAction & {\n action: typeof REQ_ACCESS_TKN | typeof REQ_PROFILE | typeof REQ_UPDATE_PROFILE;\n};\n\nexport type AUTH_ACTION =\n | REQ_ACCESS_TKN_TYPE\n | RCV_ACCESS_TKN_TYPE\n | REQ_PROFILE_TYPE\n | RCV_PROFILE_TYPE\n | REQ_UPDATE_PROFILE_TYPE\n | RCV_UPDATE_PROFILE_TYPE\n | REQUEST_FAILED_TYPE;\n\ntype Dispatch = ReduxDispatch;\n\nconst createRefreshFrame = (callback: () => void) => {\n if (process.env.SSR) return null;\n\n const body = document.body;\n const frame = document.createElement('iframe');\n\n frame.src = '/auth/refresh';\n frame.setAttribute('width', '1');\n frame.setAttribute('height', '1');\n frame.setAttribute('frameborder', '0');\n frame.onload = () => {\n callback();\n body.removeChild(frame);\n };\n body.appendChild(frame);\n};\n\nexport const getAccessToken = () => async (dispatch: Dispatch) => {\n if (requestCache.isPending(REQ_ACCESS_TKN)) {\n return;\n }\n requestCache.isPending(REQ_ACCESS_TKN, true);\n\n try {\n dispatch({ type: REQ_ACCESS_TKN });\n\n const response = await http.json(\n '/api/auth/token',\n buildGetRequest({ withCookies: true }),\n );\n http.validateResponse(response);\n dispatch({\n type: RCV_ACCESS_TKN,\n response: response.response,\n });\n } catch (_e) {\n dispatch({ type: REQUEST_FAILED, action: REQ_ACCESS_TKN });\n }\n requestCache.isPending(REQ_ACCESS_TKN, false);\n};\n\nexport const refreshAccessToken = () => (dispatch: Dispatch) =>\n createRefreshFrame(() => getAccessToken()(dispatch));\n\nexport const get = () => async (dispatch: Dispatch, getState: () => RootState) => {\n const { auth } = getState();\n if (!auth.token || requestCache.isPending(REQ_PROFILE)) {\n return;\n }\n requestCache.isPending(REQ_PROFILE, true);\n\n try {\n dispatch({ type: REQ_PROFILE });\n\n const response = await http.json(\n '/api/profile',\n buildAuthorizedGetRequest(auth.token),\n );\n http.validateResponse(response);\n dispatch({\n type: RCV_PROFILE,\n response: response.response,\n });\n } catch (_e) {\n dispatch({ type: REQUEST_FAILED, action: REQ_PROFILE });\n }\n requestCache.isPending(REQ_PROFILE, false);\n};\n\nexport const update =\n (profile: ProfileFull) => async (dispatch: Dispatch, getState: () => RootState) => {\n const { auth } = getState();\n if (!auth.token || requestCache.isPending(REQ_UPDATE_PROFILE)) {\n return;\n }\n requestCache.isPending(REQ_UPDATE_PROFILE, true);\n\n try {\n dispatch({ type: REQ_UPDATE_PROFILE });\n\n const response = await http.json(\n '/api/profile',\n buildAuthorizedPutRequest(auth.token, { content: profile }),\n );\n http.validateResponse(response);\n dispatch({\n type: RCV_UPDATE_PROFILE,\n response: response.response,\n });\n } catch (_e) {\n dispatch({ type: REQUEST_FAILED, action: REQ_UPDATE_PROFILE });\n }\n requestCache.isPending(REQ_UPDATE_PROFILE, false);\n };\n", "\uFEFFimport type { Dispatch } from '@reduxjs/toolkit';\nimport { jwtDecode } from 'jwt-decode';\nimport type { Token } from '../@types/Token';\n\nimport { refreshAccessToken } from '../actions/auth';\nimport type { RootState } from '../reducers';\n\nconst isExpired = (token: string, offset: number) => {\n try {\n const data = jwtDecode(token);\n const expires = new Date(data.exp * 1000 - offset);\n\n return expires <= new Date();\n } catch (_e) {\n return true;\n }\n};\n\nexport const getTokenEmail = (token: string) => {\n if (!token) {\n return null;\n }\n\n const data = jwtDecode(token);\n return data?.email || null;\n};\n\nconst requestTokenRenewal = (dispatch: Dispatch, getState: () => RootState) => {\n const { auth } = getState();\n if (auth.token) {\n if (isExpired(auth.token, 9 * 60 * 1000)) {\n refreshAccessToken()(dispatch);\n }\n }\n};\n\nexport const createRefreshTokenHandler = (dispatch: Dispatch, getState: () => RootState) => {\n setInterval(\n () => {\n requestTokenRenewal(dispatch, getState);\n },\n 3 * 60 * 1000,\n );\n};\n", "export class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }));\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n }\n catch (err) {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);\n }\n try {\n return JSON.parse(decoded);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);\n }\n}\n"], "mappings": "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", "names": ["REQ_ACCESS_TKN", "RCV_ACCESS_TKN", "REQ_PROFILE", "RCV_PROFILE", "REQ_UPDATE_PROFILE", "RCV_UPDATE_PROFILE", "REQUEST_FAILED", "createRefreshFrame", "callback", "body", "frame", "getAccessToken", "dispatch", "request_cache_default", "response", "json", "buildGetRequest", "validateResponse", "refreshAccessToken", "get", "getState", "auth", "buildAuthorizedGetRequest", "update", "profile", "buildAuthorizedPutRequest", "auth_exports", "__export", "createRefreshTokenHandler", "getTokenEmail", "InvalidTokenError", "b64DecodeUnicode", "str", "m", "p", "code", "base64UrlDecode", "output", "jwtDecode", "token", "options", "pos", "part", "decoded", "e", "isExpired", "token", "offset", "data", "jwtDecode", "getTokenEmail", "requestTokenRenewal", "dispatch", "getState", "auth", "refreshAccessToken", "createRefreshTokenHandler"] }