@assaf/react-one-tap
Advanced tools
| import type { Profile } from "."; | ||
| export default function decodeJWT(token: string | null): Profile | undefined; |
| import * as React from "react"; | ||
| import { OneTapOptions } from "."; | ||
| import OneTapContext from "./OneTapContext"; | ||
| export default function GoogleOneTap({ children, ...options }: { | ||
| children: React.ReactNode | ((context: typeof OneTapContext) => React.ReactNode); | ||
| } & OneTapOptions): React.FunctionComponentElement<React.ProviderProps<import("./types").OneTapContext>>; |
| export { default as GoogleOneTap } from "./GoogleOneTap"; | ||
| export type { OneTapContext, OneTapOptions, Profile } from "./types"; | ||
| export { default as useGoogleOneTap } from "./useGoogleOneTap"; |
| import * as React from "react"; | ||
| import type { OneTapContext } from "."; | ||
| declare const _default: React.Context<OneTapContext>; | ||
| export default _default; |
| /// <reference types="node" /> | ||
| import type { TokenPayload } from "google-auth-library"; | ||
| import { IncomingMessage } from "http"; | ||
| declare type Authenticated = { | ||
| status: 200; | ||
| message?: undefined; | ||
| profile: TokenPayload; | ||
| }; | ||
| declare type NotAuthenticated = { | ||
| status: 401 | 403; | ||
| message: string; | ||
| profile?: undefined; | ||
| }; | ||
| export default function authenticate({ clientId, req, }: { | ||
| clientId: string; | ||
| req: IncomingMessage; | ||
| }): Promise<Authenticated | NotAuthenticated>; | ||
| export {}; |
| export declare type OneTapOptions = { | ||
| automatic?: boolean; | ||
| clientId: string; | ||
| context?: "signin" | "signup" | "use"; | ||
| fallback?: { | ||
| buttonId: string; | ||
| size?: "small" | "medium" | "large"; | ||
| }; | ||
| reauthenticate?: number | string; | ||
| }; | ||
| export declare type OneTapContext = { | ||
| headers?: { | ||
| authorization: string; | ||
| }; | ||
| isSignedIn: boolean; | ||
| profile?: Profile; | ||
| signOut: () => void; | ||
| token: string | null; | ||
| }; | ||
| export declare type Profile = { | ||
| email: string; | ||
| email_verified: boolean; | ||
| iss: "https://accounts.google.com"; | ||
| picture: string; | ||
| sub: string; | ||
| given_name: string; | ||
| family_name: string; | ||
| name: string; | ||
| aud: string; | ||
| iat: number; | ||
| exp: number; | ||
| hd?: string; | ||
| }; |
| import type { OneTapOptions } from "."; | ||
| export default function useGoogleAPI({ clearToken, options, setToken, token, }: { | ||
| clearToken: () => void; | ||
| options: OneTapOptions; | ||
| setToken: (token: string | null) => void; | ||
| token: string | null; | ||
| }): { | ||
| reauthenticate: () => void; | ||
| signOut: () => void; | ||
| }; |
| export default function useGoogleOneTap(): import("./types").OneTapContext; |
| export default function useLocalStorage(keyName: string): { | ||
| clearToken: () => void; | ||
| setToken: (token: string | null) => void; | ||
| token: string | null; | ||
| }; |
+84
| export declare type OneTapOptions = { | ||
| // If true (default), automatically signs in user when they visit the page for | ||
| // the first time (supported browsers only), or return to the page after their | ||
| // token expired. | ||
| // | ||
| // If false, then you need to specify `fallback.buttonId`, for a button the | ||
| // user can click to sign in. | ||
| automatic?: boolean; | ||
| // The OAuth client ID for your web application. Required. | ||
| clientId: string; | ||
| // Whether user it promoted to "Sign in with Google", "Use with Google", etc. | ||
| context?: "signin" | "signup" | "use"; | ||
| // The fallback for one-tap is the Sign In with Google button. | ||
| // | ||
| // This is only if you want to use the Sign In button as fallback when one-tap | ||
| // is not available, eg Safari and iOS. | ||
| // | ||
| // You need to set fallback.buttonId, and render an empty element with the same ID. | ||
| fallback?: { | ||
| // This is the ID of the element that will contain the button. This element | ||
| // needs to be in the DOM. | ||
| buttonId: string; | ||
| size?: "small" | "medium" | "large"; | ||
| }; | ||
| // Ask user to re-authenticate before their session is about to expire. | ||
| // | ||
| // Can be expressed as number (milliseconds) or string (eg "5m", "30s"). | ||
| // Default to "5m", so user prompted to re-authenticate 5 minutes before their | ||
| // session is about to expire. | ||
| // | ||
| // Set to zero to disable. | ||
| reauthenticate?: number | string; | ||
| }; | ||
| export declare type OneTapContext = { | ||
| // Bearer token authorization header for the API call: | ||
| // | ||
| // Authorization: Bearer <token> | ||
| headers?: { authorization: string }; | ||
| isSignedIn: boolean; | ||
| // JTW token payload provides user name, email address, photo, etc. | ||
| profile?: Profile; | ||
| // Call this function to sign-out the user from this and all other tabs. | ||
| // | ||
| // You can also call this if the server responds with 403 (access token revoked). | ||
| signOut: () => void; | ||
| // This is the OAuth Bearer token. | ||
| token: string | null; | ||
| }; | ||
| export declare type Profile = { | ||
| // User's email address. | ||
| email: string; | ||
| // True if user's email address was verified | ||
| email_verified: boolean; | ||
| // Issuer of the JWT token | ||
| iss: "https://accounts.google.com"; | ||
| // User's profile picture. | ||
| picture: string; | ||
| // Unique immutable identifier of the user. | ||
| sub: string; | ||
| // User's given name | ||
| given_name: string; | ||
| // User's family name | ||
| family_name: string; | ||
| // User's full name | ||
| name: string; | ||
| // The audience for this token: same as client ID | ||
| aud: string; | ||
| // Timestamp when token was issued (Unix time, seconds) | ||
| iat: number; | ||
| // Timestamp when this token expires (Unix time, seconds) | ||
| exp: number; | ||
| // The hosted G Suite domain of the user. Available when user belongs to a hosted domain. | ||
| hd?: string; | ||
| }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"react-one-tap.cjs.development.js","sources":["../src/decodeJWT.ts","../src/OneTapContext.ts","../src/useGoogleAPI.ts","../src/useLocalStorage.ts","../src/GoogleOneTap.ts","../src/useGoogleOneTap.ts"],"sourcesContent":["import { Profile } from \"./Profile\";\n\nexport default function decodeJWT(token: string | null): Profile | undefined {\n if (!token) return;\n\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n\n try {\n const profile = JSON.parse(json);\n const { exp } = profile;\n const isExpired = exp * 1000 < Date.now();\n return isExpired ? undefined : profile;\n } catch (error) {\n return;\n }\n}\n","import * as React from \"react\";\nimport { Profile } from \"./Profile\";\n\ndeclare type OneTapContext = {\n // Bearer token authorization header for the API call:\n //\n // Authorization: Bearer <token>\n headers?: { authorization: string };\n\n isSignedIn: boolean;\n\n // JTW token payload provides user name, email address, photo, etc.\n profile?: Profile;\n\n // Call this function to sign-out the user from this and all other tabs.\n //\n // You can also call this if the server responds with 403 (access token revoked).\n signOut: () => void;\n\n // This is the OAuth Bearer token.\n token: string | null;\n};\n\nexport default React.createContext<OneTapContext>({\n isSignedIn: false,\n signOut: () => undefined,\n token: null,\n});\n","import * as React from \"react\";\nimport decodeJWT from \"./decodeJWT\";\nimport { OneTapOptions } from \"./OneTapOptions\";\n\n// https://developers.google.com/identity/gsi/web/reference/js-reference\nexport default function useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n}: {\n clearToken: () => void;\n options: OneTapOptions;\n setToken: (token: string | null) => void;\n token: string | null;\n}): {\n reauthenticate: () => void;\n signOut: () => void;\n} {\n if (!options?.clientId) throw new Error(\"Missing clientId\");\n const automatic = options.automatic ?? true;\n\n const withScript = useWithScript();\n\n withScript(function initializeAPI() {\n google.accounts.id.initialize({\n auto_select: automatic,\n callback: ({ credential }) => setToken(credential),\n client_id: options.clientId,\n context: options.context,\n });\n });\n\n React.useEffect(\n () =>\n withScript(() => {\n if (token) google.accounts.id.cancel();\n else if (automatic) promptToSignIn(options);\n else renderSignInButton(options);\n }),\n [token]\n );\n\n const reauthenticate = React.useCallback(\n () =>\n withScript(() => {\n google.accounts.id.prompt();\n }),\n [token]\n );\n\n const signOut = React.useCallback(\n () =>\n withScript(() => {\n if (!token) return;\n\n clearToken();\n\n const profile = decodeJWT(token);\n if (profile) google.accounts.id.revoke(profile.sub);\n google.accounts.id.disableAutoSelect();\n }),\n [token]\n );\n\n return { reauthenticate, signOut };\n}\n\nfunction useWithScript(): (callbackfn: () => unknown) => void {\n const [queue] = React.useState<Array<(script: HTMLScriptElement) => void>>(\n []\n );\n\n React.useEffect(function () {\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.addEventListener(\"load\", onLoad);\n document.head.appendChild(script);\n\n return function () {\n script.removeEventListener(\"load\", onLoad);\n queue.length = 0;\n };\n\n function onLoad() {\n queue.forEach((callbackfn) => callbackfn(script));\n queue.length = 0;\n }\n }, []);\n\n return function (callbackfn) {\n const isScriptLoaded =\n typeof google !== \"undefined\" && google.accounts?.id?.initialize;\n if (isScriptLoaded) callbackfn();\n else queue.push(callbackfn);\n };\n}\n\nfunction promptToSignIn(options: OneTapOptions) {\n google.accounts.id.prompt((notification) => {\n if (notification.isNotDisplayed()) renderSignInButton(options);\n });\n}\n\nfunction renderSignInButton(options: OneTapOptions) {\n const { fallback } = options;\n if (fallback) {\n const container = document.getElementById(fallback.buttonId);\n if (container) google.accounts.id.renderButton(container, fallback);\n }\n}\n\ndeclare const google: {\n accounts: {\n id: {\n cancel: () => void;\n disableAutoSelect: () => void;\n initialize: ({\n auto_select,\n callback,\n cancel_on_tap_outside,\n client_id,\n context,\n }: {\n auto_select?: boolean;\n callback?: ({\n clientId,\n credential,\n select_by,\n }: {\n clientId: string;\n credential: string;\n select_by: \"auto\";\n }) => void;\n cancel_on_tap_outside?: boolean;\n client_id: string;\n context?: \"signin\" | \"signup\" | \"use\";\n }) => void;\n prompt: (\n callback?: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n }) => void\n ) => void;\n renderButton: (\n element: HTMLElement,\n options: {\n size?: \"small\" | \"medium\" | \"large\";\n }\n ) => void;\n revoke: (identity: string, callback?: () => void) => void;\n setLogLevel: (level: \"info\" | \"warn\" | \"error\") => void;\n };\n };\n};\n","import * as React from \"react\";\n\n// We use local storage, so user doesn't have to sign in again when they refresh\n// the page, or open a new tab. And when the user signs out, they are signed\n// out of all open tabs.\nexport default function useLocalStorage(keyName: string): {\n clearToken: () => void;\n setToken: (token: string | null) => void;\n token: string | null;\n} {\n const [token, setToken] = React.useState(() =>\n typeof localStorage !== \"undefined\" ? localStorage.getItem(keyName) : null\n );\n\n React.useEffect(function watchOtherTabs() {\n window.addEventListener(\"storage\", onStorageEvent);\n return () => window.removeEventListener(\"storage\", onStorageEvent);\n\n function onStorageEvent(event: StorageEvent) {\n if (event.key === keyName) setToken(event.newValue);\n }\n }, []);\n\n React.useEffect(\n function persistToken() {\n if (token) window.localStorage.setItem(keyName, token);\n else window.localStorage.removeItem(keyName);\n },\n [token]\n );\n\n return {\n token,\n setToken,\n clearToken: () => setToken(null),\n };\n}\n","import * as React from \"react\";\nimport decodeJWT from \"./decodeJWT\";\nimport OneTapContext from \"./OneTapContext\";\nimport { OneTapOptions } from \"./OneTapOptions\";\nimport { Profile } from \"./Profile\";\nimport useGoogleAPI from \"./useGoogleAPI\";\nimport useLocalStorage from \"./useLocalStorage\";\n\n// Ask user to re-authenticate 5 mintues before their session is about to\n// expire.\nconst defaultReauthenticate = \"5m\";\n\nexport default function GoogleOneTap({\n children,\n ...options\n}: {\n children:\n | React.ReactNode\n | ((context: typeof OneTapContext) => React.ReactNode);\n} & OneTapOptions) {\n const { clearToken, setToken, token } = useLocalStorage(\n \"google-one-tap-token\"\n );\n const profile = React.useMemo(() => decodeJWT(token), [token]);\n\n const { reauthenticate, signOut } = useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n });\n\n useSignOutWhenTokenExpires({ profile, signOut });\n useReauthenticateBeforeTokenExpires({ options, profile, reauthenticate });\n\n const context: React.ContextType<typeof OneTapContext> = {\n headers: token ? { authorization: `Bearer ${token}` } : undefined,\n isSignedIn: Boolean(token),\n profile,\n signOut,\n token,\n };\n\n return React.createElement(\n OneTapContext.Provider,\n { value: context },\n typeof children === \"function\" || children instanceof Function\n ? children(context)\n : children\n );\n}\n\nfunction useSignOutWhenTokenExpires({\n profile,\n signOut,\n}: {\n profile?: Profile;\n signOut: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n if (expiresIn < 0) return;\n\n const timeout = setTimeout(signOut, expiresIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction useReauthenticateBeforeTokenExpires({\n options,\n profile,\n reauthenticate,\n}: {\n options: OneTapOptions;\n profile?: Profile;\n reauthenticate: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const leadTime = duration(options.reauthenticate ?? defaultReauthenticate);\n if (!leadTime) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n const promptIn = expiresIn - duration(leadTime);\n if (promptIn < 0) return;\n\n const timeout = setTimeout(reauthenticate, promptIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction duration(value: number | string) {\n if (typeof value === \"number\") return Math.max(value, 0);\n if (typeof value !== \"string\") throw new Error(`Invalid value: ${value}`);\n\n const match =\n /^(\\d+)\\s*(seconds?|secs?|s|minutes?|mins?|m|milliseconds?|ms)?$/i.exec(\n value\n );\n if (!match) return 0;\n\n const number = Math.max(parseFloat(match[1]), 0);\n const type = match[2];\n if (!type) return number;\n\n return /^m|milliseconds?$/i.test(type)\n ? number\n : /minutes?|mins?|m$/i.test(type)\n ? number * 60 * 1000\n : number * 1000;\n}\n","import { useContext } from \"react\";\nimport OneTapContext from \"./OneTapContext\";\n\nexport default function useGoogleOneTap() {\n return useContext(OneTapContext);\n}\n"],"names":["decodeJWT","token","base64Url","split","base64","replace","json","decodeURIComponent","window","atob","map","c","charCodeAt","toString","slice","join","profile","JSON","parse","exp","isExpired","Date","now","undefined","error","React","isSignedIn","signOut","useGoogleAPI","clearToken","options","setToken","clientId","Error","automatic","withScript","useWithScript","initializeAPI","google","accounts","id","initialize","auto_select","callback","credential","client_id","context","cancel","promptToSignIn","renderSignInButton","reauthenticate","prompt","revoke","sub","disableAutoSelect","queue","script","document","createElement","src","addEventListener","onLoad","head","appendChild","removeEventListener","length","forEach","callbackfn","isScriptLoaded","push","notification","isNotDisplayed","fallback","container","getElementById","buttonId","renderButton","useLocalStorage","keyName","localStorage","getItem","watchOtherTabs","onStorageEvent","event","key","newValue","persistToken","setItem","removeItem","defaultReauthenticate","GoogleOneTap","children","useSignOutWhenTokenExpires","useReauthenticateBeforeTokenExpires","headers","authorization","Boolean","OneTapContext","Provider","value","Function","expiresIn","timeout","setTimeout","clearTimeout","leadTime","duration","promptIn","Math","max","match","exec","number","parseFloat","type","test","useGoogleOneTap","useContext"],"mappings":"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"} | ||
| {"version":3,"file":"react-one-tap.cjs.development.js","sources":["../src/decodeJWT.ts","../src/OneTapContext.ts","../src/useGoogleAPI.ts","../src/useLocalStorage.ts","../src/GoogleOneTap.ts","../src/useGoogleOneTap.ts"],"sourcesContent":["import type { Profile } from \".\";\n\nexport default function decodeJWT(token: string | null): Profile | undefined {\n if (!token) return;\n\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n\n try {\n const profile = JSON.parse(json);\n const { exp } = profile;\n const isExpired = exp * 1000 < Date.now();\n return isExpired ? undefined : profile;\n } catch (error) {\n return;\n }\n}\n","import * as React from \"react\";\nimport type { OneTapContext } from \".\";\n\nexport default React.createContext<OneTapContext>({\n isSignedIn: false,\n signOut: () => undefined,\n token: null,\n});\n","import * as React from \"react\";\nimport type { OneTapOptions } from \".\";\nimport decodeJWT from \"./decodeJWT\";\n\n// https://developers.google.com/identity/gsi/web/reference/js-reference\nexport default function useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n}: {\n clearToken: () => void;\n options: OneTapOptions;\n setToken: (token: string | null) => void;\n token: string | null;\n}): {\n reauthenticate: () => void;\n signOut: () => void;\n} {\n if (!options?.clientId) throw new Error(\"Missing clientId\");\n const automatic = options.automatic ?? true;\n\n const withScript = useWithScript();\n\n withScript(function initializeAPI() {\n google.accounts.id.initialize({\n auto_select: automatic,\n callback: ({ credential }) => setToken(credential),\n client_id: options.clientId,\n context: options.context,\n });\n });\n\n React.useEffect(\n () =>\n withScript(() => {\n if (token) google.accounts.id.cancel();\n else if (automatic) promptToSignIn(options);\n else renderSignInButton(options);\n }),\n [token]\n );\n\n const reauthenticate = React.useCallback(\n () =>\n withScript(() => {\n google.accounts.id.prompt();\n }),\n [token]\n );\n\n const signOut = React.useCallback(\n () =>\n withScript(() => {\n if (!token) return;\n\n clearToken();\n\n const profile = decodeJWT(token);\n if (profile) google.accounts.id.revoke(profile.sub);\n google.accounts.id.disableAutoSelect();\n }),\n [token]\n );\n\n return { reauthenticate, signOut };\n}\n\nfunction useWithScript(): (callbackfn: () => unknown) => void {\n const [queue] = React.useState<Array<(script: HTMLScriptElement) => void>>(\n []\n );\n\n React.useEffect(function () {\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.addEventListener(\"load\", onLoad);\n document.head.appendChild(script);\n\n return function () {\n script.removeEventListener(\"load\", onLoad);\n queue.length = 0;\n };\n\n function onLoad() {\n queue.forEach((callbackfn) => callbackfn(script));\n queue.length = 0;\n }\n }, []);\n\n return function (callbackfn) {\n const isScriptLoaded =\n typeof google !== \"undefined\" && google.accounts?.id?.initialize;\n if (isScriptLoaded) callbackfn();\n else queue.push(callbackfn);\n };\n}\n\nfunction promptToSignIn(options: OneTapOptions) {\n google.accounts.id.prompt((notification) => {\n if (notification.isNotDisplayed()) renderSignInButton(options);\n });\n}\n\nfunction renderSignInButton(options: OneTapOptions) {\n const { fallback } = options;\n if (fallback) {\n const container = document.getElementById(fallback.buttonId);\n if (container) google.accounts.id.renderButton(container, fallback);\n }\n}\n\ndeclare const google: {\n accounts: {\n id: {\n cancel: () => void;\n disableAutoSelect: () => void;\n initialize: ({\n auto_select,\n callback,\n cancel_on_tap_outside,\n client_id,\n context,\n }: {\n auto_select?: boolean;\n callback?: ({\n clientId,\n credential,\n select_by,\n }: {\n clientId: string;\n credential: string;\n select_by: \"auto\";\n }) => void;\n cancel_on_tap_outside?: boolean;\n client_id: string;\n context?: \"signin\" | \"signup\" | \"use\";\n }) => void;\n prompt: (\n callback?: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n }) => void\n ) => void;\n renderButton: (\n element: HTMLElement,\n options: {\n size?: \"small\" | \"medium\" | \"large\";\n }\n ) => void;\n revoke: (identity: string, callback?: () => void) => void;\n setLogLevel: (level: \"info\" | \"warn\" | \"error\") => void;\n };\n };\n};\n","import * as React from \"react\";\n\n// We use local storage, so user doesn't have to sign in again when they refresh\n// the page, or open a new tab. And when the user signs out, they are signed\n// out of all open tabs.\nexport default function useLocalStorage(keyName: string): {\n clearToken: () => void;\n setToken: (token: string | null) => void;\n token: string | null;\n} {\n const [token, setToken] = React.useState(() =>\n typeof localStorage !== \"undefined\" ? localStorage.getItem(keyName) : null\n );\n\n React.useEffect(function watchOtherTabs() {\n window.addEventListener(\"storage\", onStorageEvent);\n return () => window.removeEventListener(\"storage\", onStorageEvent);\n\n function onStorageEvent(event: StorageEvent) {\n if (event.key === keyName) setToken(event.newValue);\n }\n }, []);\n\n React.useEffect(\n function persistToken() {\n if (token) window.localStorage.setItem(keyName, token);\n else window.localStorage.removeItem(keyName);\n },\n [token]\n );\n\n return {\n token,\n setToken,\n clearToken: () => setToken(null),\n };\n}\n","import * as React from \"react\";\nimport { OneTapOptions, Profile } from \".\";\nimport decodeJWT from \"./decodeJWT\";\nimport OneTapContext from \"./OneTapContext\";\nimport useGoogleAPI from \"./useGoogleAPI\";\nimport useLocalStorage from \"./useLocalStorage\";\n\n// Ask user to re-authenticate 5 mintues before their session is about to\n// expire.\nconst defaultReauthenticate = \"5m\";\n\nexport default function GoogleOneTap({\n children,\n ...options\n}: {\n children:\n | React.ReactNode\n | ((context: typeof OneTapContext) => React.ReactNode);\n} & OneTapOptions) {\n const { clearToken, setToken, token } = useLocalStorage(\n \"google-one-tap-token\"\n );\n const profile = React.useMemo(() => decodeJWT(token), [token]);\n\n const { reauthenticate, signOut } = useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n });\n\n useSignOutWhenTokenExpires({ profile, signOut });\n useReauthenticateBeforeTokenExpires({ options, profile, reauthenticate });\n\n const context: React.ContextType<typeof OneTapContext> = {\n headers: token ? { authorization: `Bearer ${token}` } : undefined,\n isSignedIn: Boolean(token),\n profile,\n signOut,\n token,\n };\n\n return React.createElement(\n OneTapContext.Provider,\n { value: context },\n typeof children === \"function\" || children instanceof Function\n ? children(context)\n : children\n );\n}\n\nfunction useSignOutWhenTokenExpires({\n profile,\n signOut,\n}: {\n profile?: Profile;\n signOut: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n if (expiresIn < 0) return;\n\n const timeout = setTimeout(signOut, expiresIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction useReauthenticateBeforeTokenExpires({\n options,\n profile,\n reauthenticate,\n}: {\n options: OneTapOptions;\n profile?: Profile;\n reauthenticate: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const leadTime = duration(options.reauthenticate ?? defaultReauthenticate);\n if (!leadTime) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n const promptIn = expiresIn - duration(leadTime);\n if (promptIn < 0) return;\n\n const timeout = setTimeout(reauthenticate, promptIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction duration(value: number | string) {\n if (typeof value === \"number\") return Math.max(value, 0);\n if (typeof value !== \"string\") throw new Error(`Invalid value: ${value}`);\n\n const match =\n /^(\\d+)\\s*(seconds?|secs?|s|minutes?|mins?|m|milliseconds?|ms)?$/i.exec(\n value\n );\n if (!match) return 0;\n\n const number = Math.max(parseFloat(match[1]), 0);\n const type = match[2];\n if (!type) return number;\n\n return /^m|milliseconds?$/i.test(type)\n ? number\n : /minutes?|mins?|m$/i.test(type)\n ? number * 60 * 1000\n : number * 1000;\n}\n","import { useContext } from \"react\";\nimport OneTapContext from \"./OneTapContext\";\n\nexport default function useGoogleOneTap() {\n return useContext(OneTapContext);\n}\n"],"names":["decodeJWT","token","base64Url","split","base64","replace","json","decodeURIComponent","window","atob","map","c","charCodeAt","toString","slice","join","profile","JSON","parse","exp","isExpired","Date","now","undefined","error","React","isSignedIn","signOut","useGoogleAPI","clearToken","options","setToken","clientId","Error","automatic","withScript","useWithScript","initializeAPI","google","accounts","id","initialize","auto_select","callback","credential","client_id","context","cancel","promptToSignIn","renderSignInButton","reauthenticate","prompt","revoke","sub","disableAutoSelect","queue","script","document","createElement","src","addEventListener","onLoad","head","appendChild","removeEventListener","length","forEach","callbackfn","isScriptLoaded","push","notification","isNotDisplayed","fallback","container","getElementById","buttonId","renderButton","useLocalStorage","keyName","localStorage","getItem","watchOtherTabs","onStorageEvent","event","key","newValue","persistToken","setItem","removeItem","defaultReauthenticate","GoogleOneTap","children","useSignOutWhenTokenExpires","useReauthenticateBeforeTokenExpires","headers","authorization","Boolean","OneTapContext","Provider","value","Function","expiresIn","timeout","setTimeout","clearTimeout","leadTime","duration","promptIn","Math","max","match","exec","number","parseFloat","type","test","useGoogleOneTap","useContext"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"react-one-tap.cjs.production.min.js","sources":["../src/decodeJWT.ts","../src/OneTapContext.ts","../src/useGoogleAPI.ts","../src/GoogleOneTap.ts","../src/useLocalStorage.ts","../src/useGoogleOneTap.ts"],"sourcesContent":["import { Profile } from \"./Profile\";\n\nexport default function decodeJWT(token: string | null): Profile | undefined {\n if (!token) return;\n\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n\n try {\n const profile = JSON.parse(json);\n const { exp } = profile;\n const isExpired = exp * 1000 < Date.now();\n return isExpired ? undefined : profile;\n } catch (error) {\n return;\n }\n}\n","import * as React from \"react\";\nimport { Profile } from \"./Profile\";\n\ndeclare type OneTapContext = {\n // Bearer token authorization header for the API call:\n //\n // Authorization: Bearer <token>\n headers?: { authorization: string };\n\n isSignedIn: boolean;\n\n // JTW token payload provides user name, email address, photo, etc.\n profile?: Profile;\n\n // Call this function to sign-out the user from this and all other tabs.\n //\n // You can also call this if the server responds with 403 (access token revoked).\n signOut: () => void;\n\n // This is the OAuth Bearer token.\n token: string | null;\n};\n\nexport default React.createContext<OneTapContext>({\n isSignedIn: false,\n signOut: () => undefined,\n token: null,\n});\n","import * as React from \"react\";\nimport decodeJWT from \"./decodeJWT\";\nimport { OneTapOptions } from \"./OneTapOptions\";\n\n// https://developers.google.com/identity/gsi/web/reference/js-reference\nexport default function useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n}: {\n clearToken: () => void;\n options: OneTapOptions;\n setToken: (token: string | null) => void;\n token: string | null;\n}): {\n reauthenticate: () => void;\n signOut: () => void;\n} {\n if (!options?.clientId) throw new Error(\"Missing clientId\");\n const automatic = options.automatic ?? true;\n\n const withScript = useWithScript();\n\n withScript(function initializeAPI() {\n google.accounts.id.initialize({\n auto_select: automatic,\n callback: ({ credential }) => setToken(credential),\n client_id: options.clientId,\n context: options.context,\n });\n });\n\n React.useEffect(\n () =>\n withScript(() => {\n if (token) google.accounts.id.cancel();\n else if (automatic) promptToSignIn(options);\n else renderSignInButton(options);\n }),\n [token]\n );\n\n const reauthenticate = React.useCallback(\n () =>\n withScript(() => {\n google.accounts.id.prompt();\n }),\n [token]\n );\n\n const signOut = React.useCallback(\n () =>\n withScript(() => {\n if (!token) return;\n\n clearToken();\n\n const profile = decodeJWT(token);\n if (profile) google.accounts.id.revoke(profile.sub);\n google.accounts.id.disableAutoSelect();\n }),\n [token]\n );\n\n return { reauthenticate, signOut };\n}\n\nfunction useWithScript(): (callbackfn: () => unknown) => void {\n const [queue] = React.useState<Array<(script: HTMLScriptElement) => void>>(\n []\n );\n\n React.useEffect(function () {\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.addEventListener(\"load\", onLoad);\n document.head.appendChild(script);\n\n return function () {\n script.removeEventListener(\"load\", onLoad);\n queue.length = 0;\n };\n\n function onLoad() {\n queue.forEach((callbackfn) => callbackfn(script));\n queue.length = 0;\n }\n }, []);\n\n return function (callbackfn) {\n const isScriptLoaded =\n typeof google !== \"undefined\" && google.accounts?.id?.initialize;\n if (isScriptLoaded) callbackfn();\n else queue.push(callbackfn);\n };\n}\n\nfunction promptToSignIn(options: OneTapOptions) {\n google.accounts.id.prompt((notification) => {\n if (notification.isNotDisplayed()) renderSignInButton(options);\n });\n}\n\nfunction renderSignInButton(options: OneTapOptions) {\n const { fallback } = options;\n if (fallback) {\n const container = document.getElementById(fallback.buttonId);\n if (container) google.accounts.id.renderButton(container, fallback);\n }\n}\n\ndeclare const google: {\n accounts: {\n id: {\n cancel: () => void;\n disableAutoSelect: () => void;\n initialize: ({\n auto_select,\n callback,\n cancel_on_tap_outside,\n client_id,\n context,\n }: {\n auto_select?: boolean;\n callback?: ({\n clientId,\n credential,\n select_by,\n }: {\n clientId: string;\n credential: string;\n select_by: \"auto\";\n }) => void;\n cancel_on_tap_outside?: boolean;\n client_id: string;\n context?: \"signin\" | \"signup\" | \"use\";\n }) => void;\n prompt: (\n callback?: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n }) => void\n ) => void;\n renderButton: (\n element: HTMLElement,\n options: {\n size?: \"small\" | \"medium\" | \"large\";\n }\n ) => void;\n revoke: (identity: string, callback?: () => void) => void;\n setLogLevel: (level: \"info\" | \"warn\" | \"error\") => void;\n };\n };\n};\n","import * as React from \"react\";\nimport decodeJWT from \"./decodeJWT\";\nimport OneTapContext from \"./OneTapContext\";\nimport { OneTapOptions } from \"./OneTapOptions\";\nimport { Profile } from \"./Profile\";\nimport useGoogleAPI from \"./useGoogleAPI\";\nimport useLocalStorage from \"./useLocalStorage\";\n\n// Ask user to re-authenticate 5 mintues before their session is about to\n// expire.\nconst defaultReauthenticate = \"5m\";\n\nexport default function GoogleOneTap({\n children,\n ...options\n}: {\n children:\n | React.ReactNode\n | ((context: typeof OneTapContext) => React.ReactNode);\n} & OneTapOptions) {\n const { clearToken, setToken, token } = useLocalStorage(\n \"google-one-tap-token\"\n );\n const profile = React.useMemo(() => decodeJWT(token), [token]);\n\n const { reauthenticate, signOut } = useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n });\n\n useSignOutWhenTokenExpires({ profile, signOut });\n useReauthenticateBeforeTokenExpires({ options, profile, reauthenticate });\n\n const context: React.ContextType<typeof OneTapContext> = {\n headers: token ? { authorization: `Bearer ${token}` } : undefined,\n isSignedIn: Boolean(token),\n profile,\n signOut,\n token,\n };\n\n return React.createElement(\n OneTapContext.Provider,\n { value: context },\n typeof children === \"function\" || children instanceof Function\n ? children(context)\n : children\n );\n}\n\nfunction useSignOutWhenTokenExpires({\n profile,\n signOut,\n}: {\n profile?: Profile;\n signOut: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n if (expiresIn < 0) return;\n\n const timeout = setTimeout(signOut, expiresIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction useReauthenticateBeforeTokenExpires({\n options,\n profile,\n reauthenticate,\n}: {\n options: OneTapOptions;\n profile?: Profile;\n reauthenticate: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const leadTime = duration(options.reauthenticate ?? defaultReauthenticate);\n if (!leadTime) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n const promptIn = expiresIn - duration(leadTime);\n if (promptIn < 0) return;\n\n const timeout = setTimeout(reauthenticate, promptIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction duration(value: number | string) {\n if (typeof value === \"number\") return Math.max(value, 0);\n if (typeof value !== \"string\") throw new Error(`Invalid value: ${value}`);\n\n const match =\n /^(\\d+)\\s*(seconds?|secs?|s|minutes?|mins?|m|milliseconds?|ms)?$/i.exec(\n value\n );\n if (!match) return 0;\n\n const number = Math.max(parseFloat(match[1]), 0);\n const type = match[2];\n if (!type) return number;\n\n return /^m|milliseconds?$/i.test(type)\n ? number\n : /minutes?|mins?|m$/i.test(type)\n ? number * 60 * 1000\n : number * 1000;\n}\n","import * as React from \"react\";\n\n// We use local storage, so user doesn't have to sign in again when they refresh\n// the page, or open a new tab. And when the user signs out, they are signed\n// out of all open tabs.\nexport default function useLocalStorage(keyName: string): {\n clearToken: () => void;\n setToken: (token: string | null) => void;\n token: string | null;\n} {\n const [token, setToken] = React.useState(() =>\n typeof localStorage !== \"undefined\" ? localStorage.getItem(keyName) : null\n );\n\n React.useEffect(function watchOtherTabs() {\n window.addEventListener(\"storage\", onStorageEvent);\n return () => window.removeEventListener(\"storage\", onStorageEvent);\n\n function onStorageEvent(event: StorageEvent) {\n if (event.key === keyName) setToken(event.newValue);\n }\n }, []);\n\n React.useEffect(\n function persistToken() {\n if (token) window.localStorage.setItem(keyName, token);\n else window.localStorage.removeItem(keyName);\n },\n [token]\n );\n\n return {\n token,\n setToken,\n clearToken: () => setToken(null),\n };\n}\n","import { useContext } from \"react\";\nimport OneTapContext from \"./OneTapContext\";\n\nexport default function useGoogleOneTap() {\n return useContext(OneTapContext);\n}\n"],"names":["decodeJWT","token","base64","split","replace","json","decodeURIComponent","window","atob","map","c","charCodeAt","toString","slice","join","profile","JSON","parse","exp","Date","now","undefined","error","React","isSignedIn","signOut","renderSignInButton","options","fallback","container","document","getElementById","buttonId","google","accounts","id","renderButton","duration","value","Math","max","Error","match","exec","number","parseFloat","type","test","children","keyName","localStorage","getItem","setToken","addEventListener","onStorageEvent","removeEventListener","event","key","newValue","setItem","removeItem","clearToken","useLocalStorage","clientId","queue","automatic","withScript","script","createElement","src","onLoad","head","appendChild","length","forEach","callbackfn","_google$accounts","_google$accounts$id","initialize","push","auto_select","callback","credential","client_id","context","cancel","prompt","notification","isNotDisplayed","promptToSignIn","reauthenticate","revoke","sub","disableAutoSelect","useGoogleAPI","expiresIn","timeout","setTimeout","clearTimeout","useSignOutWhenTokenExpires","leadTime","promptIn","useReauthenticateBeforeTokenExpires","headers","authorization","Boolean","OneTapContext","Provider","Function","useContext"],"mappings":"oGAEwBA,EAAUC,MAC3BA,OAGCC,EADYD,EAAME,MAAM,KAAK,GACVC,QAAQ,KAAM,KAAKA,QAAQ,KAAM,KACpDC,EAAOC,mBACXC,OACGC,KAAKN,GACLC,MAAM,IACNM,KAAI,SAACC,SAAM,KAAO,KAAOA,EAAEC,WAAW,GAAGC,SAAS,KAAKC,OAAO,MAC9DC,KAAK,aAIFC,EAAUC,KAAKC,MAAMZ,UAEH,IADRU,EAARG,IACuBC,KAAKC,WACjBC,EAAYN,EAC/B,MAAOO,YCGX,MAAeC,gBAAmC,CAChDC,YAAY,EACZC,QAAS,aACTxB,MAAO,OC8ET,SAASyB,EAAmBC,OAClBC,EAAaD,EAAbC,YACJA,EAAU,KACNC,EAAYC,SAASC,eAAeH,EAASI,UAC/CH,GAAWI,OAAOC,SAASC,GAAGC,aAAaP,EAAWD,uBCd9D,SAASS,EAASC,MACK,iBAAVA,EAAoB,OAAOC,KAAKC,IAAIF,EAAO,MACjC,iBAAVA,EAAoB,MAAM,IAAIG,wBAAwBH,OAE3DI,EACJ,mEAAmEC,KACjEL,OAECI,EAAO,OAAO,MAEbE,EAASL,KAAKC,IAAIK,WAAWH,EAAM,IAAK,GACxCI,EAAOJ,EAAM,UACdI,EAEE,qBAAqBC,KAAKD,GAC7BF,EACA,qBAAqBG,KAAKD,GACjB,GAATF,EAAc,IACL,IAATA,EANcA,uCA7FlBI,IAAAA,SACGrB,qJCTmCsB,SAKZ1B,YAAe,iBACf,oBAAjB2B,aAA+BA,aAAaC,QAAQF,GAAW,QADjEhD,OAAOmD,cAId7B,aAAgB,kBACdhB,OAAO8C,iBAAiB,UAAWC,GAC5B,kBAAM/C,OAAOgD,oBAAoB,UAAWD,aAE1CA,EAAeE,GAClBA,EAAMC,MAAQR,GAASG,EAASI,EAAME,aAE3C,IAEHnC,aACE,WACMtB,EAAOM,OAAO2C,aAAaS,QAAQV,EAAShD,GAC3CM,OAAO2C,aAAaU,WAAWX,KAEtC,CAAChD,IAGI,CACLA,MAAAA,EACAmD,SAAAA,EACAS,WAAY,kBAAMT,EAAS,QDdWU,CACtC,wBADMD,IAAAA,WAAYT,IAAAA,SAAUnD,IAAAA,MAGxBc,EAAUQ,WAAc,kBAAMvB,EAAUC,KAAQ,CAACA,wBDjBvD4D,IAAAA,WACAlC,IAAAA,QACAyB,IAAAA,SACAnD,IAAAA,eAUK0B,IAAAA,EAASoC,SAAU,MAAM,IAAItB,MAAM,wBAkDjCuB,EAjDDC,WAAYtC,EAAQsC,cAEpBC,GA+CCF,EAASzC,WACd,OAGFA,aAAgB,eACR4C,EAASrC,SAASsC,cAAc,iBACtCD,EAAOE,IAAM,yCACbF,EAAOd,iBAAiB,OAAQiB,GAChCxC,SAASyC,KAAKC,YAAYL,GAEnB,WACLA,EAAOZ,oBAAoB,OAAQe,GACnCN,EAAMS,OAAS,YAGRH,IACPN,EAAMU,SAAQ,SAACC,UAAeA,EAAWR,MACzCH,EAAMS,OAAS,KAEhB,IAEI,SAAUE,WAEK,oBAAX1C,kBAA0BA,OAAOC,oBAAP0C,EAAiBzC,WAAjB0C,EAAqBC,YACpCH,IACfX,EAAMe,KAAKJ,YAtElBT,GAAW,WACTjC,OAAOC,SAASC,GAAG2C,WAAW,CAC5BE,YAAaf,EACbgB,SAAU,mBAAoB7B,IAAjB8B,aACbC,UAAWxD,EAAQoC,SACnBqB,QAASzD,EAAQyD,aAIrB7D,aACE,kBACE2C,GAAW,WACLjE,EAAOgC,OAAOC,SAASC,GAAGkD,SACrBpB,EA6DjB,SAAwBtC,GACtBM,OAAOC,SAASC,GAAGmD,QAAO,SAACC,GACrBA,EAAaC,kBAAkB9D,EAAmBC,MA/D9B8D,CAAe9D,GAC9BD,EAAmBC,QAE5B,CAAC1B,IAyBI,CAAEyF,eAtBcnE,eACrB,kBACE2C,GAAW,WACTjC,OAAOC,SAASC,GAAGmD,cAEvB,CAACrF,IAiBsBwB,QAdTF,eACd,kBACE2C,GAAW,cACJjE,GAEL4D,QAEM9C,EAAUf,EAAUC,GACtBc,GAASkB,OAAOC,SAASC,GAAGwD,OAAO5E,EAAQ6E,KAC/C3D,OAAOC,SAASC,GAAG0D,0BAEvB,CAAC5F,KCrCiC6F,CAAa,CAC/CjC,WAAAA,EACAlC,QAAAA,EACAyB,SAAAA,EACAnD,MAAAA,IAJMyF,IAAAA,eAAgBjE,IAAAA,SA2B1B,gBACEV,IAAAA,QACAU,IAAAA,QAKAF,aAAgB,cACTR,OAECgF,EAA0B,IAAdhF,EAAQG,IAAaC,KAAKC,WACxC2E,EAAY,QAEVC,EAAUC,WAAWxE,EAASsE,UAC7B,kBAAMG,aAAaF,QACzB,OAACjF,SAAAA,EAASG,MAnCbiF,CAA2B,CAAEpF,QAAAA,EAASU,QAAAA,IAsCxC,gBACEE,IAAAA,QACAZ,IAAAA,QACA2E,IAAAA,eAMAnE,aAAgB,oBACTR,OAECqF,EAAW/D,WAASV,EAAQ+D,kBAxER,SAyErBU,OAGCC,EAD0B,IAAdtF,EAAQG,IAAaC,KAAKC,MACfiB,EAAS+D,QAClCC,EAAW,QAETL,EAAUC,WAAWP,EAAgBW,UACpC,kBAAMH,aAAaF,SACzB,OAACjF,SAAAA,EAASG,MA1DboF,CAAoC,CAAE3E,QAAAA,EAASZ,QAAAA,EAAS2E,eAAAA,QAElDN,EAAmD,CACvDmB,QAAStG,EAAQ,CAAEuG,wBAAyBvG,QAAYoB,EACxDG,WAAYiF,QAAQxG,GACpBc,QAAAA,EACAU,QAAAA,EACAxB,MAAAA,UAGKsB,gBACLmF,EAAcC,SACd,CAAErE,MAAO8C,GACW,mBAAbpC,GAA2BA,aAAoB4D,SAClD5D,EAASoC,GACTpC,8CE5CC6D,aAAWH"} | ||
| {"version":3,"file":"react-one-tap.cjs.production.min.js","sources":["../src/decodeJWT.ts","../src/OneTapContext.ts","../src/useGoogleAPI.ts","../src/GoogleOneTap.ts","../src/useLocalStorage.ts","../src/useGoogleOneTap.ts"],"sourcesContent":["import type { Profile } from \".\";\n\nexport default function decodeJWT(token: string | null): Profile | undefined {\n if (!token) return;\n\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n\n try {\n const profile = JSON.parse(json);\n const { exp } = profile;\n const isExpired = exp * 1000 < Date.now();\n return isExpired ? undefined : profile;\n } catch (error) {\n return;\n }\n}\n","import * as React from \"react\";\nimport type { OneTapContext } from \".\";\n\nexport default React.createContext<OneTapContext>({\n isSignedIn: false,\n signOut: () => undefined,\n token: null,\n});\n","import * as React from \"react\";\nimport type { OneTapOptions } from \".\";\nimport decodeJWT from \"./decodeJWT\";\n\n// https://developers.google.com/identity/gsi/web/reference/js-reference\nexport default function useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n}: {\n clearToken: () => void;\n options: OneTapOptions;\n setToken: (token: string | null) => void;\n token: string | null;\n}): {\n reauthenticate: () => void;\n signOut: () => void;\n} {\n if (!options?.clientId) throw new Error(\"Missing clientId\");\n const automatic = options.automatic ?? true;\n\n const withScript = useWithScript();\n\n withScript(function initializeAPI() {\n google.accounts.id.initialize({\n auto_select: automatic,\n callback: ({ credential }) => setToken(credential),\n client_id: options.clientId,\n context: options.context,\n });\n });\n\n React.useEffect(\n () =>\n withScript(() => {\n if (token) google.accounts.id.cancel();\n else if (automatic) promptToSignIn(options);\n else renderSignInButton(options);\n }),\n [token]\n );\n\n const reauthenticate = React.useCallback(\n () =>\n withScript(() => {\n google.accounts.id.prompt();\n }),\n [token]\n );\n\n const signOut = React.useCallback(\n () =>\n withScript(() => {\n if (!token) return;\n\n clearToken();\n\n const profile = decodeJWT(token);\n if (profile) google.accounts.id.revoke(profile.sub);\n google.accounts.id.disableAutoSelect();\n }),\n [token]\n );\n\n return { reauthenticate, signOut };\n}\n\nfunction useWithScript(): (callbackfn: () => unknown) => void {\n const [queue] = React.useState<Array<(script: HTMLScriptElement) => void>>(\n []\n );\n\n React.useEffect(function () {\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.addEventListener(\"load\", onLoad);\n document.head.appendChild(script);\n\n return function () {\n script.removeEventListener(\"load\", onLoad);\n queue.length = 0;\n };\n\n function onLoad() {\n queue.forEach((callbackfn) => callbackfn(script));\n queue.length = 0;\n }\n }, []);\n\n return function (callbackfn) {\n const isScriptLoaded =\n typeof google !== \"undefined\" && google.accounts?.id?.initialize;\n if (isScriptLoaded) callbackfn();\n else queue.push(callbackfn);\n };\n}\n\nfunction promptToSignIn(options: OneTapOptions) {\n google.accounts.id.prompt((notification) => {\n if (notification.isNotDisplayed()) renderSignInButton(options);\n });\n}\n\nfunction renderSignInButton(options: OneTapOptions) {\n const { fallback } = options;\n if (fallback) {\n const container = document.getElementById(fallback.buttonId);\n if (container) google.accounts.id.renderButton(container, fallback);\n }\n}\n\ndeclare const google: {\n accounts: {\n id: {\n cancel: () => void;\n disableAutoSelect: () => void;\n initialize: ({\n auto_select,\n callback,\n cancel_on_tap_outside,\n client_id,\n context,\n }: {\n auto_select?: boolean;\n callback?: ({\n clientId,\n credential,\n select_by,\n }: {\n clientId: string;\n credential: string;\n select_by: \"auto\";\n }) => void;\n cancel_on_tap_outside?: boolean;\n client_id: string;\n context?: \"signin\" | \"signup\" | \"use\";\n }) => void;\n prompt: (\n callback?: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n }) => void\n ) => void;\n renderButton: (\n element: HTMLElement,\n options: {\n size?: \"small\" | \"medium\" | \"large\";\n }\n ) => void;\n revoke: (identity: string, callback?: () => void) => void;\n setLogLevel: (level: \"info\" | \"warn\" | \"error\") => void;\n };\n };\n};\n","import * as React from \"react\";\nimport { OneTapOptions, Profile } from \".\";\nimport decodeJWT from \"./decodeJWT\";\nimport OneTapContext from \"./OneTapContext\";\nimport useGoogleAPI from \"./useGoogleAPI\";\nimport useLocalStorage from \"./useLocalStorage\";\n\n// Ask user to re-authenticate 5 mintues before their session is about to\n// expire.\nconst defaultReauthenticate = \"5m\";\n\nexport default function GoogleOneTap({\n children,\n ...options\n}: {\n children:\n | React.ReactNode\n | ((context: typeof OneTapContext) => React.ReactNode);\n} & OneTapOptions) {\n const { clearToken, setToken, token } = useLocalStorage(\n \"google-one-tap-token\"\n );\n const profile = React.useMemo(() => decodeJWT(token), [token]);\n\n const { reauthenticate, signOut } = useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n });\n\n useSignOutWhenTokenExpires({ profile, signOut });\n useReauthenticateBeforeTokenExpires({ options, profile, reauthenticate });\n\n const context: React.ContextType<typeof OneTapContext> = {\n headers: token ? { authorization: `Bearer ${token}` } : undefined,\n isSignedIn: Boolean(token),\n profile,\n signOut,\n token,\n };\n\n return React.createElement(\n OneTapContext.Provider,\n { value: context },\n typeof children === \"function\" || children instanceof Function\n ? children(context)\n : children\n );\n}\n\nfunction useSignOutWhenTokenExpires({\n profile,\n signOut,\n}: {\n profile?: Profile;\n signOut: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n if (expiresIn < 0) return;\n\n const timeout = setTimeout(signOut, expiresIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction useReauthenticateBeforeTokenExpires({\n options,\n profile,\n reauthenticate,\n}: {\n options: OneTapOptions;\n profile?: Profile;\n reauthenticate: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const leadTime = duration(options.reauthenticate ?? defaultReauthenticate);\n if (!leadTime) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n const promptIn = expiresIn - duration(leadTime);\n if (promptIn < 0) return;\n\n const timeout = setTimeout(reauthenticate, promptIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction duration(value: number | string) {\n if (typeof value === \"number\") return Math.max(value, 0);\n if (typeof value !== \"string\") throw new Error(`Invalid value: ${value}`);\n\n const match =\n /^(\\d+)\\s*(seconds?|secs?|s|minutes?|mins?|m|milliseconds?|ms)?$/i.exec(\n value\n );\n if (!match) return 0;\n\n const number = Math.max(parseFloat(match[1]), 0);\n const type = match[2];\n if (!type) return number;\n\n return /^m|milliseconds?$/i.test(type)\n ? number\n : /minutes?|mins?|m$/i.test(type)\n ? number * 60 * 1000\n : number * 1000;\n}\n","import * as React from \"react\";\n\n// We use local storage, so user doesn't have to sign in again when they refresh\n// the page, or open a new tab. And when the user signs out, they are signed\n// out of all open tabs.\nexport default function useLocalStorage(keyName: string): {\n clearToken: () => void;\n setToken: (token: string | null) => void;\n token: string | null;\n} {\n const [token, setToken] = React.useState(() =>\n typeof localStorage !== \"undefined\" ? localStorage.getItem(keyName) : null\n );\n\n React.useEffect(function watchOtherTabs() {\n window.addEventListener(\"storage\", onStorageEvent);\n return () => window.removeEventListener(\"storage\", onStorageEvent);\n\n function onStorageEvent(event: StorageEvent) {\n if (event.key === keyName) setToken(event.newValue);\n }\n }, []);\n\n React.useEffect(\n function persistToken() {\n if (token) window.localStorage.setItem(keyName, token);\n else window.localStorage.removeItem(keyName);\n },\n [token]\n );\n\n return {\n token,\n setToken,\n clearToken: () => setToken(null),\n };\n}\n","import { useContext } from \"react\";\nimport OneTapContext from \"./OneTapContext\";\n\nexport default function useGoogleOneTap() {\n return useContext(OneTapContext);\n}\n"],"names":["decodeJWT","token","base64","split","replace","json","decodeURIComponent","window","atob","map","c","charCodeAt","toString","slice","join","profile","JSON","parse","exp","Date","now","undefined","error","React","isSignedIn","signOut","renderSignInButton","options","fallback","container","document","getElementById","buttonId","google","accounts","id","renderButton","duration","value","Math","max","Error","match","exec","number","parseFloat","type","test","children","keyName","localStorage","getItem","setToken","addEventListener","onStorageEvent","removeEventListener","event","key","newValue","setItem","removeItem","clearToken","useLocalStorage","clientId","queue","automatic","withScript","script","createElement","src","onLoad","head","appendChild","length","forEach","callbackfn","_google$accounts","_google$accounts$id","initialize","push","auto_select","callback","credential","client_id","context","cancel","prompt","notification","isNotDisplayed","promptToSignIn","reauthenticate","revoke","sub","disableAutoSelect","useGoogleAPI","expiresIn","timeout","setTimeout","clearTimeout","useSignOutWhenTokenExpires","leadTime","promptIn","useReauthenticateBeforeTokenExpires","headers","authorization","Boolean","OneTapContext","Provider","Function","useContext"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"react-one-tap.esm.js","sources":["../src/decodeJWT.ts","../src/OneTapContext.ts","../src/useGoogleAPI.ts","../src/useLocalStorage.ts","../src/GoogleOneTap.ts","../src/useGoogleOneTap.ts"],"sourcesContent":["import { Profile } from \"./Profile\";\n\nexport default function decodeJWT(token: string | null): Profile | undefined {\n if (!token) return;\n\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n\n try {\n const profile = JSON.parse(json);\n const { exp } = profile;\n const isExpired = exp * 1000 < Date.now();\n return isExpired ? undefined : profile;\n } catch (error) {\n return;\n }\n}\n","import * as React from \"react\";\nimport { Profile } from \"./Profile\";\n\ndeclare type OneTapContext = {\n // Bearer token authorization header for the API call:\n //\n // Authorization: Bearer <token>\n headers?: { authorization: string };\n\n isSignedIn: boolean;\n\n // JTW token payload provides user name, email address, photo, etc.\n profile?: Profile;\n\n // Call this function to sign-out the user from this and all other tabs.\n //\n // You can also call this if the server responds with 403 (access token revoked).\n signOut: () => void;\n\n // This is the OAuth Bearer token.\n token: string | null;\n};\n\nexport default React.createContext<OneTapContext>({\n isSignedIn: false,\n signOut: () => undefined,\n token: null,\n});\n","import * as React from \"react\";\nimport decodeJWT from \"./decodeJWT\";\nimport { OneTapOptions } from \"./OneTapOptions\";\n\n// https://developers.google.com/identity/gsi/web/reference/js-reference\nexport default function useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n}: {\n clearToken: () => void;\n options: OneTapOptions;\n setToken: (token: string | null) => void;\n token: string | null;\n}): {\n reauthenticate: () => void;\n signOut: () => void;\n} {\n if (!options?.clientId) throw new Error(\"Missing clientId\");\n const automatic = options.automatic ?? true;\n\n const withScript = useWithScript();\n\n withScript(function initializeAPI() {\n google.accounts.id.initialize({\n auto_select: automatic,\n callback: ({ credential }) => setToken(credential),\n client_id: options.clientId,\n context: options.context,\n });\n });\n\n React.useEffect(\n () =>\n withScript(() => {\n if (token) google.accounts.id.cancel();\n else if (automatic) promptToSignIn(options);\n else renderSignInButton(options);\n }),\n [token]\n );\n\n const reauthenticate = React.useCallback(\n () =>\n withScript(() => {\n google.accounts.id.prompt();\n }),\n [token]\n );\n\n const signOut = React.useCallback(\n () =>\n withScript(() => {\n if (!token) return;\n\n clearToken();\n\n const profile = decodeJWT(token);\n if (profile) google.accounts.id.revoke(profile.sub);\n google.accounts.id.disableAutoSelect();\n }),\n [token]\n );\n\n return { reauthenticate, signOut };\n}\n\nfunction useWithScript(): (callbackfn: () => unknown) => void {\n const [queue] = React.useState<Array<(script: HTMLScriptElement) => void>>(\n []\n );\n\n React.useEffect(function () {\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.addEventListener(\"load\", onLoad);\n document.head.appendChild(script);\n\n return function () {\n script.removeEventListener(\"load\", onLoad);\n queue.length = 0;\n };\n\n function onLoad() {\n queue.forEach((callbackfn) => callbackfn(script));\n queue.length = 0;\n }\n }, []);\n\n return function (callbackfn) {\n const isScriptLoaded =\n typeof google !== \"undefined\" && google.accounts?.id?.initialize;\n if (isScriptLoaded) callbackfn();\n else queue.push(callbackfn);\n };\n}\n\nfunction promptToSignIn(options: OneTapOptions) {\n google.accounts.id.prompt((notification) => {\n if (notification.isNotDisplayed()) renderSignInButton(options);\n });\n}\n\nfunction renderSignInButton(options: OneTapOptions) {\n const { fallback } = options;\n if (fallback) {\n const container = document.getElementById(fallback.buttonId);\n if (container) google.accounts.id.renderButton(container, fallback);\n }\n}\n\ndeclare const google: {\n accounts: {\n id: {\n cancel: () => void;\n disableAutoSelect: () => void;\n initialize: ({\n auto_select,\n callback,\n cancel_on_tap_outside,\n client_id,\n context,\n }: {\n auto_select?: boolean;\n callback?: ({\n clientId,\n credential,\n select_by,\n }: {\n clientId: string;\n credential: string;\n select_by: \"auto\";\n }) => void;\n cancel_on_tap_outside?: boolean;\n client_id: string;\n context?: \"signin\" | \"signup\" | \"use\";\n }) => void;\n prompt: (\n callback?: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n }) => void\n ) => void;\n renderButton: (\n element: HTMLElement,\n options: {\n size?: \"small\" | \"medium\" | \"large\";\n }\n ) => void;\n revoke: (identity: string, callback?: () => void) => void;\n setLogLevel: (level: \"info\" | \"warn\" | \"error\") => void;\n };\n };\n};\n","import * as React from \"react\";\n\n// We use local storage, so user doesn't have to sign in again when they refresh\n// the page, or open a new tab. And when the user signs out, they are signed\n// out of all open tabs.\nexport default function useLocalStorage(keyName: string): {\n clearToken: () => void;\n setToken: (token: string | null) => void;\n token: string | null;\n} {\n const [token, setToken] = React.useState(() =>\n typeof localStorage !== \"undefined\" ? localStorage.getItem(keyName) : null\n );\n\n React.useEffect(function watchOtherTabs() {\n window.addEventListener(\"storage\", onStorageEvent);\n return () => window.removeEventListener(\"storage\", onStorageEvent);\n\n function onStorageEvent(event: StorageEvent) {\n if (event.key === keyName) setToken(event.newValue);\n }\n }, []);\n\n React.useEffect(\n function persistToken() {\n if (token) window.localStorage.setItem(keyName, token);\n else window.localStorage.removeItem(keyName);\n },\n [token]\n );\n\n return {\n token,\n setToken,\n clearToken: () => setToken(null),\n };\n}\n","import * as React from \"react\";\nimport decodeJWT from \"./decodeJWT\";\nimport OneTapContext from \"./OneTapContext\";\nimport { OneTapOptions } from \"./OneTapOptions\";\nimport { Profile } from \"./Profile\";\nimport useGoogleAPI from \"./useGoogleAPI\";\nimport useLocalStorage from \"./useLocalStorage\";\n\n// Ask user to re-authenticate 5 mintues before their session is about to\n// expire.\nconst defaultReauthenticate = \"5m\";\n\nexport default function GoogleOneTap({\n children,\n ...options\n}: {\n children:\n | React.ReactNode\n | ((context: typeof OneTapContext) => React.ReactNode);\n} & OneTapOptions) {\n const { clearToken, setToken, token } = useLocalStorage(\n \"google-one-tap-token\"\n );\n const profile = React.useMemo(() => decodeJWT(token), [token]);\n\n const { reauthenticate, signOut } = useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n });\n\n useSignOutWhenTokenExpires({ profile, signOut });\n useReauthenticateBeforeTokenExpires({ options, profile, reauthenticate });\n\n const context: React.ContextType<typeof OneTapContext> = {\n headers: token ? { authorization: `Bearer ${token}` } : undefined,\n isSignedIn: Boolean(token),\n profile,\n signOut,\n token,\n };\n\n return React.createElement(\n OneTapContext.Provider,\n { value: context },\n typeof children === \"function\" || children instanceof Function\n ? children(context)\n : children\n );\n}\n\nfunction useSignOutWhenTokenExpires({\n profile,\n signOut,\n}: {\n profile?: Profile;\n signOut: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n if (expiresIn < 0) return;\n\n const timeout = setTimeout(signOut, expiresIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction useReauthenticateBeforeTokenExpires({\n options,\n profile,\n reauthenticate,\n}: {\n options: OneTapOptions;\n profile?: Profile;\n reauthenticate: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const leadTime = duration(options.reauthenticate ?? defaultReauthenticate);\n if (!leadTime) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n const promptIn = expiresIn - duration(leadTime);\n if (promptIn < 0) return;\n\n const timeout = setTimeout(reauthenticate, promptIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction duration(value: number | string) {\n if (typeof value === \"number\") return Math.max(value, 0);\n if (typeof value !== \"string\") throw new Error(`Invalid value: ${value}`);\n\n const match =\n /^(\\d+)\\s*(seconds?|secs?|s|minutes?|mins?|m|milliseconds?|ms)?$/i.exec(\n value\n );\n if (!match) return 0;\n\n const number = Math.max(parseFloat(match[1]), 0);\n const type = match[2];\n if (!type) return number;\n\n return /^m|milliseconds?$/i.test(type)\n ? number\n : /minutes?|mins?|m$/i.test(type)\n ? number * 60 * 1000\n : number * 1000;\n}\n","import { useContext } from \"react\";\nimport OneTapContext from \"./OneTapContext\";\n\nexport default function useGoogleOneTap() {\n return useContext(OneTapContext);\n}\n"],"names":["decodeJWT","token","base64Url","split","base64","replace","json","decodeURIComponent","window","atob","map","c","charCodeAt","toString","slice","join","profile","JSON","parse","exp","isExpired","Date","now","undefined","error","React","isSignedIn","signOut","useGoogleAPI","clearToken","options","setToken","clientId","Error","automatic","withScript","useWithScript","initializeAPI","google","accounts","id","initialize","auto_select","callback","credential","client_id","context","cancel","promptToSignIn","renderSignInButton","reauthenticate","prompt","revoke","sub","disableAutoSelect","queue","script","document","createElement","src","addEventListener","onLoad","head","appendChild","removeEventListener","length","forEach","callbackfn","isScriptLoaded","push","notification","isNotDisplayed","fallback","container","getElementById","buttonId","renderButton","useLocalStorage","keyName","localStorage","getItem","watchOtherTabs","onStorageEvent","event","key","newValue","persistToken","setItem","removeItem","defaultReauthenticate","GoogleOneTap","children","useSignOutWhenTokenExpires","useReauthenticateBeforeTokenExpires","headers","authorization","Boolean","OneTapContext","Provider","value","Function","expiresIn","timeout","setTimeout","clearTimeout","leadTime","duration","promptIn","Math","max","match","exec","number","parseFloat","type","test","useGoogleOneTap","useContext"],"mappings":"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"} | ||
| {"version":3,"file":"react-one-tap.esm.js","sources":["../src/decodeJWT.ts","../src/OneTapContext.ts","../src/useGoogleAPI.ts","../src/useLocalStorage.ts","../src/GoogleOneTap.ts","../src/useGoogleOneTap.ts"],"sourcesContent":["import type { Profile } from \".\";\n\nexport default function decodeJWT(token: string | null): Profile | undefined {\n if (!token) return;\n\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n\n try {\n const profile = JSON.parse(json);\n const { exp } = profile;\n const isExpired = exp * 1000 < Date.now();\n return isExpired ? undefined : profile;\n } catch (error) {\n return;\n }\n}\n","import * as React from \"react\";\nimport type { OneTapContext } from \".\";\n\nexport default React.createContext<OneTapContext>({\n isSignedIn: false,\n signOut: () => undefined,\n token: null,\n});\n","import * as React from \"react\";\nimport type { OneTapOptions } from \".\";\nimport decodeJWT from \"./decodeJWT\";\n\n// https://developers.google.com/identity/gsi/web/reference/js-reference\nexport default function useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n}: {\n clearToken: () => void;\n options: OneTapOptions;\n setToken: (token: string | null) => void;\n token: string | null;\n}): {\n reauthenticate: () => void;\n signOut: () => void;\n} {\n if (!options?.clientId) throw new Error(\"Missing clientId\");\n const automatic = options.automatic ?? true;\n\n const withScript = useWithScript();\n\n withScript(function initializeAPI() {\n google.accounts.id.initialize({\n auto_select: automatic,\n callback: ({ credential }) => setToken(credential),\n client_id: options.clientId,\n context: options.context,\n });\n });\n\n React.useEffect(\n () =>\n withScript(() => {\n if (token) google.accounts.id.cancel();\n else if (automatic) promptToSignIn(options);\n else renderSignInButton(options);\n }),\n [token]\n );\n\n const reauthenticate = React.useCallback(\n () =>\n withScript(() => {\n google.accounts.id.prompt();\n }),\n [token]\n );\n\n const signOut = React.useCallback(\n () =>\n withScript(() => {\n if (!token) return;\n\n clearToken();\n\n const profile = decodeJWT(token);\n if (profile) google.accounts.id.revoke(profile.sub);\n google.accounts.id.disableAutoSelect();\n }),\n [token]\n );\n\n return { reauthenticate, signOut };\n}\n\nfunction useWithScript(): (callbackfn: () => unknown) => void {\n const [queue] = React.useState<Array<(script: HTMLScriptElement) => void>>(\n []\n );\n\n React.useEffect(function () {\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.addEventListener(\"load\", onLoad);\n document.head.appendChild(script);\n\n return function () {\n script.removeEventListener(\"load\", onLoad);\n queue.length = 0;\n };\n\n function onLoad() {\n queue.forEach((callbackfn) => callbackfn(script));\n queue.length = 0;\n }\n }, []);\n\n return function (callbackfn) {\n const isScriptLoaded =\n typeof google !== \"undefined\" && google.accounts?.id?.initialize;\n if (isScriptLoaded) callbackfn();\n else queue.push(callbackfn);\n };\n}\n\nfunction promptToSignIn(options: OneTapOptions) {\n google.accounts.id.prompt((notification) => {\n if (notification.isNotDisplayed()) renderSignInButton(options);\n });\n}\n\nfunction renderSignInButton(options: OneTapOptions) {\n const { fallback } = options;\n if (fallback) {\n const container = document.getElementById(fallback.buttonId);\n if (container) google.accounts.id.renderButton(container, fallback);\n }\n}\n\ndeclare const google: {\n accounts: {\n id: {\n cancel: () => void;\n disableAutoSelect: () => void;\n initialize: ({\n auto_select,\n callback,\n cancel_on_tap_outside,\n client_id,\n context,\n }: {\n auto_select?: boolean;\n callback?: ({\n clientId,\n credential,\n select_by,\n }: {\n clientId: string;\n credential: string;\n select_by: \"auto\";\n }) => void;\n cancel_on_tap_outside?: boolean;\n client_id: string;\n context?: \"signin\" | \"signup\" | \"use\";\n }) => void;\n prompt: (\n callback?: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n }) => void\n ) => void;\n renderButton: (\n element: HTMLElement,\n options: {\n size?: \"small\" | \"medium\" | \"large\";\n }\n ) => void;\n revoke: (identity: string, callback?: () => void) => void;\n setLogLevel: (level: \"info\" | \"warn\" | \"error\") => void;\n };\n };\n};\n","import * as React from \"react\";\n\n// We use local storage, so user doesn't have to sign in again when they refresh\n// the page, or open a new tab. And when the user signs out, they are signed\n// out of all open tabs.\nexport default function useLocalStorage(keyName: string): {\n clearToken: () => void;\n setToken: (token: string | null) => void;\n token: string | null;\n} {\n const [token, setToken] = React.useState(() =>\n typeof localStorage !== \"undefined\" ? localStorage.getItem(keyName) : null\n );\n\n React.useEffect(function watchOtherTabs() {\n window.addEventListener(\"storage\", onStorageEvent);\n return () => window.removeEventListener(\"storage\", onStorageEvent);\n\n function onStorageEvent(event: StorageEvent) {\n if (event.key === keyName) setToken(event.newValue);\n }\n }, []);\n\n React.useEffect(\n function persistToken() {\n if (token) window.localStorage.setItem(keyName, token);\n else window.localStorage.removeItem(keyName);\n },\n [token]\n );\n\n return {\n token,\n setToken,\n clearToken: () => setToken(null),\n };\n}\n","import * as React from \"react\";\nimport { OneTapOptions, Profile } from \".\";\nimport decodeJWT from \"./decodeJWT\";\nimport OneTapContext from \"./OneTapContext\";\nimport useGoogleAPI from \"./useGoogleAPI\";\nimport useLocalStorage from \"./useLocalStorage\";\n\n// Ask user to re-authenticate 5 mintues before their session is about to\n// expire.\nconst defaultReauthenticate = \"5m\";\n\nexport default function GoogleOneTap({\n children,\n ...options\n}: {\n children:\n | React.ReactNode\n | ((context: typeof OneTapContext) => React.ReactNode);\n} & OneTapOptions) {\n const { clearToken, setToken, token } = useLocalStorage(\n \"google-one-tap-token\"\n );\n const profile = React.useMemo(() => decodeJWT(token), [token]);\n\n const { reauthenticate, signOut } = useGoogleAPI({\n clearToken,\n options,\n setToken,\n token,\n });\n\n useSignOutWhenTokenExpires({ profile, signOut });\n useReauthenticateBeforeTokenExpires({ options, profile, reauthenticate });\n\n const context: React.ContextType<typeof OneTapContext> = {\n headers: token ? { authorization: `Bearer ${token}` } : undefined,\n isSignedIn: Boolean(token),\n profile,\n signOut,\n token,\n };\n\n return React.createElement(\n OneTapContext.Provider,\n { value: context },\n typeof children === \"function\" || children instanceof Function\n ? children(context)\n : children\n );\n}\n\nfunction useSignOutWhenTokenExpires({\n profile,\n signOut,\n}: {\n profile?: Profile;\n signOut: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n if (expiresIn < 0) return;\n\n const timeout = setTimeout(signOut, expiresIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction useReauthenticateBeforeTokenExpires({\n options,\n profile,\n reauthenticate,\n}: {\n options: OneTapOptions;\n profile?: Profile;\n reauthenticate: () => void;\n}) {\n React.useEffect(() => {\n if (!profile) return;\n\n const leadTime = duration(options.reauthenticate ?? defaultReauthenticate);\n if (!leadTime) return;\n\n const expiresIn = profile.exp * 1000 - Date.now();\n const promptIn = expiresIn - duration(leadTime);\n if (promptIn < 0) return;\n\n const timeout = setTimeout(reauthenticate, promptIn);\n return () => clearTimeout(timeout);\n }, [profile?.exp]);\n}\n\nfunction duration(value: number | string) {\n if (typeof value === \"number\") return Math.max(value, 0);\n if (typeof value !== \"string\") throw new Error(`Invalid value: ${value}`);\n\n const match =\n /^(\\d+)\\s*(seconds?|secs?|s|minutes?|mins?|m|milliseconds?|ms)?$/i.exec(\n value\n );\n if (!match) return 0;\n\n const number = Math.max(parseFloat(match[1]), 0);\n const type = match[2];\n if (!type) return number;\n\n return /^m|milliseconds?$/i.test(type)\n ? number\n : /minutes?|mins?|m$/i.test(type)\n ? number * 60 * 1000\n : number * 1000;\n}\n","import { useContext } from \"react\";\nimport OneTapContext from \"./OneTapContext\";\n\nexport default function useGoogleOneTap() {\n return useContext(OneTapContext);\n}\n"],"names":["decodeJWT","token","base64Url","split","base64","replace","json","decodeURIComponent","window","atob","map","c","charCodeAt","toString","slice","join","profile","JSON","parse","exp","isExpired","Date","now","undefined","error","React","isSignedIn","signOut","useGoogleAPI","clearToken","options","setToken","clientId","Error","automatic","withScript","useWithScript","initializeAPI","google","accounts","id","initialize","auto_select","callback","credential","client_id","context","cancel","promptToSignIn","renderSignInButton","reauthenticate","prompt","revoke","sub","disableAutoSelect","queue","script","document","createElement","src","addEventListener","onLoad","head","appendChild","removeEventListener","length","forEach","callbackfn","isScriptLoaded","push","notification","isNotDisplayed","fallback","container","getElementById","buttonId","renderButton","useLocalStorage","keyName","localStorage","getItem","watchOtherTabs","onStorageEvent","event","key","newValue","persistToken","setItem","removeItem","defaultReauthenticate","GoogleOneTap","children","useSignOutWhenTokenExpires","useReauthenticateBeforeTokenExpires","headers","authorization","Boolean","OneTapContext","Provider","value","Function","expiresIn","timeout","setTimeout","clearTimeout","leadTime","duration","promptIn","Math","max","match","exec","number","parseFloat","type","test","useGoogleOneTap","useContext"],"mappings":"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"} |
+3
-3
| { | ||
| "name": "@assaf/react-one-tap", | ||
| "version": "2.0.0", | ||
| "version": "2.0.1", | ||
| "description": "Google One Tap for React", | ||
| "main": "dist/index.js", | ||
| "typings": "dist/index.d.ts", | ||
| "module": "dist/react-one-tap.esm.js", | ||
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "start": "tsdx watch", | ||
| "build": "tsdx build && tsc src/server/authenticate.ts --outDir dist/server && cp src/server/authenticate.ts dist/server", | ||
| "build": "tsdx build && tsc -p src/server", | ||
| "lint": "tsdx lint", | ||
@@ -12,0 +12,0 @@ "prepare": "tsdx build" |
+1
-3
@@ -111,3 +111,2 @@ React components for [one-tap sign-in](https://developers.google.com/identity/one-tap/) with your Google account. | ||
| } else { | ||
| if (response.status === 403) signOut(); | ||
| const { error } = await response.json(); | ||
@@ -136,3 +135,2 @@ throw new Error(error); | ||
| } else { | ||
| if (response.status === 403) signOut(); | ||
| const { error } = await response.json(); | ||
@@ -162,3 +160,3 @@ throw new Error(error); | ||
| ```typescript | ||
| import { authenticate } from "@assaf/react-one-tap/dist/server"; | ||
| import authenticate from "@assaf/react-one-tap/dist/server"; | ||
@@ -165,0 +163,0 @@ const clientId = process.env.GOOGLE_CLIENT_ID; |
+1
-1
@@ -1,2 +0,2 @@ | ||
| import { Profile } from "./Profile"; | ||
| import type { Profile } from "."; | ||
@@ -3,0 +3,0 @@ export default function decodeJWT(token: string | null): Profile | undefined { |
| import * as React from "react"; | ||
| import { OneTapOptions, Profile } from "."; | ||
| import decodeJWT from "./decodeJWT"; | ||
| import OneTapContext from "./OneTapContext"; | ||
| import { OneTapOptions } from "./OneTapOptions"; | ||
| import { Profile } from "./Profile"; | ||
| import useGoogleAPI from "./useGoogleAPI"; | ||
@@ -7,0 +6,0 @@ import useLocalStorage from "./useLocalStorage"; |
+1
-2
| export { default as GoogleOneTap } from "./GoogleOneTap"; | ||
| export type { OneTapOptions } from "./OneTapOptions"; | ||
| export type { Profile } from "./Profile"; | ||
| export type { OneTapContext, OneTapOptions, Profile } from "./types"; | ||
| export { default as useGoogleOneTap } from "./useGoogleOneTap"; |
+1
-21
| import * as React from "react"; | ||
| import { Profile } from "./Profile"; | ||
| import type { OneTapContext } from "."; | ||
| declare type OneTapContext = { | ||
| // Bearer token authorization header for the API call: | ||
| // | ||
| // Authorization: Bearer <token> | ||
| headers?: { authorization: string }; | ||
| isSignedIn: boolean; | ||
| // JTW token payload provides user name, email address, photo, etc. | ||
| profile?: Profile; | ||
| // Call this function to sign-out the user from this and all other tabs. | ||
| // | ||
| // You can also call this if the server responds with 403 (access token revoked). | ||
| signOut: () => void; | ||
| // This is the OAuth Bearer token. | ||
| token: string | null; | ||
| }; | ||
| export default React.createContext<OneTapContext>({ | ||
@@ -25,0 +5,0 @@ isSignedIn: false, |
@@ -6,6 +6,4 @@ { | ||
| "declarationDir": "../../dist/server", | ||
| "forceConsistentCasingInFileNames": true, | ||
| "outDir": "../../dist/server", | ||
| "strict": true, | ||
| "typeRoots": ["node_modules/@types"] | ||
| "sourceMap": true | ||
| }, | ||
@@ -12,0 +10,0 @@ "exclude": ["node_modules"], |
| import * as React from "react"; | ||
| import type { OneTapOptions } from "."; | ||
| import decodeJWT from "./decodeJWT"; | ||
| import { OneTapOptions } from "./OneTapOptions"; | ||
@@ -5,0 +5,0 @@ // https://developers.google.com/identity/gsi/web/reference/js-reference |
| export declare type OneTapOptions = { | ||
| // If true (default), automatically signs in user when they visit the page for | ||
| // the first time (supported browsers only), or return to the page after their | ||
| // token expired. | ||
| // | ||
| // If false, then you need to specify `fallback.buttonId`, for a button the | ||
| // user can click to sign in. | ||
| automatic?: boolean; | ||
| // The OAuth client ID for your web application. Required. | ||
| clientId: string; | ||
| // Whether user it promoted to "Sign in with Google", "Use with Google", etc. | ||
| context?: "signin" | "signup" | "use"; | ||
| // The fallback for one-tap is the Sign In with Google button. | ||
| // | ||
| // This is only if you want to use the Sign In button as fallback when one-tap | ||
| // is not available, eg Safari and iOS. | ||
| // | ||
| // You need to set fallback.buttonId, and render an empty element with the same ID. | ||
| fallback?: { | ||
| // This is the ID of the element that will contain the button. This element | ||
| // needs to be in the DOM. | ||
| buttonId: string; | ||
| size?: "small" | "medium" | "large"; | ||
| }; | ||
| // Ask user to re-authenticate before their session is about to expire. | ||
| // | ||
| // Can be expressed as number (milliseconds) or string (eg "5m", "30s"). | ||
| // Default to "5m", so user prompted to re-authenticate 5 minutes before their | ||
| // session is about to expire. | ||
| // | ||
| // Set to zero to disable. | ||
| reauthenticate?: number | string; | ||
| }; |
| export declare type Profile = { | ||
| // User's email address. | ||
| email: string; | ||
| // True if user's email address was verified | ||
| email_verified: boolean; | ||
| // Issuer of the JWT token | ||
| iss: "https://accounts.google.com"; | ||
| // User's profile picture. | ||
| picture: string; | ||
| // Unique immutable identifier of the user. | ||
| sub: string; | ||
| // User's given name | ||
| given_name: string; | ||
| // User's family name | ||
| family_name: string; | ||
| // User's full name | ||
| name: string; | ||
| // The audience for this token: same as client ID | ||
| aud: string; | ||
| // Timestamp when token was issued (Unix time, seconds) | ||
| iat: number; | ||
| // Timestamp when this token expires (Unix time, seconds) | ||
| exp: number; | ||
| // The hosted G Suite domain of the user. Available when user belongs to a hosted domain. | ||
| hd?: string; | ||
| }; |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
94531
0.59%28
40%1013
8.34%192
-1.03%