@stack-spot/auth-react 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ ## [1.7.0](https://github.com/stack-spot/portal-auth-js/compare/auth-react@v1.6.0...auth-react@v1.7.0) (2024-07-19)
4
+
5
+
6
+ ### Features
7
+
8
+ * default values for url parameters ([d394d03](https://github.com/stack-spot/portal-auth-js/commit/d394d03c780a193fa6e9a656f4b7bd0e9b8b731b))
9
+
10
+ ## [1.6.0](https://github.com/stack-spot/portal-auth-js/compare/auth-react-v1.5.0...auth-react@v1.6.0) (2024-07-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * @stack-spot/auth-react ([22fd98c](https://github.com/stack-spot/portal-auth-js/commit/22fd98c2f251c491d158b5014dabed7d714683ad))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * delete dist before building ([97be04f](https://github.com/stack-spot/portal-auth-js/commit/97be04fe136b15c86e250c57c1e31006694bfce2))
21
+ * Update color bg on Login Page ([12c5d09](https://github.com/stack-spot/portal-auth-js/commit/12c5d0905af6c956f41acd5d81c9950f11038e1d))
package/out/index.d.ts CHANGED
@@ -26,9 +26,24 @@ type LoginProps = {
26
26
  };
27
27
  declare const Login: ({ onSubmit, initialValue, welcomeText, removeLoadingOnSuccess, className, style, banner, loginTypes }: LoginProps) => react_jsx_runtime.JSX.Element;
28
28
 
29
- interface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant' | 'redirectUrl'> {
30
- loginUrl: string;
29
+ interface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant'> {
30
+ /**
31
+ * The URL to redirect to when the user logs out.
32
+ * @default location.origin
33
+ */
34
+ loginUrl?: string;
35
+ /**
36
+ * The URL to redirect to when the login completes in the authentication app. If not provided, will be the same as `loginUrl`.
37
+ * @default loginUrl
38
+ */
39
+ redirectUrl?: string;
40
+ /**
41
+ * Forbidden authentication types to this Session Manager.
42
+ */
31
43
  blockedAuthTypes?: ThirdPartyAuthType[];
44
+ /**
45
+ * A URL to send login events to (observability).
46
+ */
32
47
  rdUrl?: string;
33
48
  }
34
49
  type ChangeListener = (session: Session | undefined) => void;
package/out/index.js CHANGED
@@ -32,7 +32,7 @@ const LoginBox = styledComponents.styled.form`
32
32
 
33
33
  .separator {
34
34
  padding: 0 8px;
35
- background-color: ${portalTheme.theme.color.light["400"]};
35
+ background-color: ${portalTheme.theme.color.light["300"]};
36
36
  color: ${portalTheme.theme.color.light["700"]};
37
37
  display: flex;
38
38
  flex-direction: row;
@@ -174,8 +174,11 @@ const _SessionManager = class _SessionManager {
174
174
  __publicField(this, "auth");
175
175
  __publicField(this, "config");
176
176
  __publicField(this, "changeListeners", []);
177
+ config.loginUrl || (config.loginUrl = location.origin);
178
+ const redirectUrl = (config.redirectUrl || config.loginUrl).replace(/([^/])$/, "$1/");
177
179
  this.config = config;
178
180
  this.auth = new auth.AuthManager(__spreadProps$1(__spreadValues$1({}, config), {
181
+ redirectUrl,
179
182
  storage: localStorage,
180
183
  sessionPersistence: {
181
184
  load: () => localStorage.getItem(sessionKey),
@@ -233,7 +236,7 @@ const _SessionManager = class _SessionManager {
233
236
  this.current = void 0;
234
237
  localStorage.removeItem(sessionKey);
235
238
  sessionCookie.delete();
236
- if (redirectToLogin)
239
+ if (redirectToLogin && this.config.loginUrl)
237
240
  await redirect(this.config.loginUrl);
238
241
  }
239
242
  async logout() {
package/out/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/Login.tsx","../src/utils/cookies.ts","../src/utils/redirect.ts","../src/SessionManager.ts","../src/Authenticated.tsx","../src/hooks.ts"],"sourcesContent":["/* eslint-disable max-len */\nimport { Button, IconBox, Input, Text } from '@citric/core'\nimport { Github } from '@citric/icons'\nimport { LoadingCircular } from '@citric/ui'\nimport { BannerWarning } from '@stack-spot/portal-components'\nimport { MiniLogo } from '@stack-spot/portal-components/svg'\nimport { theme } from '@stack-spot/portal-theme'\nimport { Dictionary, useTranslate } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { styled } from 'styled-components'\n\nexport type LoginType = 'sso' | 'idp'\n\ninterface BaseData {\n type: LoginType,\n}\n\ninterface SSOData extends BaseData {\n type: 'sso',\n email: string,\n}\n\ninterface IDPData extends BaseData {\n type: 'idp',\n provider: 'external-idp:github',\n}\n\ntype LoginData = SSOData | IDPData\n\nexport type LoginProps = {\n initialValue?: string,\n onSubmit: (data: LoginData) => Promise<void>,\n welcomeText?: string,\n removeLoadingOnSuccess?: boolean,\n className?: string,\n style?: React.CSSProperties,\n banner?: React.ReactNode,\n loginTypes?: LoginType[]\n}\n\nconst LoginBox = styled.form`\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 24px;\n\n header {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n }\n\n .title {\n font-size: 1rem;\n }\n\n .separator {\n padding: 0 8px;\n background-color: ${theme.color.light['400']};\n color: ${theme.color.light['700']};\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 20px;\n margin: 0;\n\n &:before, &:after {\n content: '';\n height: 1px;\n flex: 1;\n background-color: ${theme.color.light['600']};\n }\n }\n\n .error {\n color: ${theme.color.danger['500']};\n line-height: 1.5rem;\n }\n`\n\nexport const Login = ({ onSubmit, initialValue = '', welcomeText, removeLoadingOnSuccess, className, style, banner, loginTypes = ['idp', 'sso'] }: LoginProps) => {\n const t = useTranslate(dictionary)\n const searchParams = new URLSearchParams(location.search)\n const [error, setError] = useState(searchParams.get('error_description') || searchParams.get('error') || '')\n const [loading, setLoading] = useState(false)\n const [email, setEmail] = useState(initialValue)\n const disabled = !email.match(/\\w+@\\w+/)\n const idpLoginEnabled = loginTypes.includes('idp')\n const ssoLoginEnabled = loginTypes.includes('sso')\n\n async function login(type: LoginType) {\n setError('')\n setLoading(true)\n try {\n const data: LoginData = type === 'sso' ? { type: 'sso', email } : { type: 'idp', provider: 'external-idp:github' }\n await onSubmit(data)\n if (removeLoadingOnSuccess) setLoading(false)\n } catch (error: any) {\n setLoading(false)\n setError(error.message || error.toString())\n }\n }\n\n function submitForm(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n if (disabled) return\n login('sso')\n }\n\n return (\n <>\n <LoginBox onSubmit={submitForm} className={className} style={style}>\n <header>\n <MiniLogo />\n <Text className=\"title\">{welcomeText || t.welcome}</Text>\n </header>\n {ssoLoginEnabled && <>\n <Input name=\"email\" value={email} onChange={e => setEmail(e.target.value)} placeholder={t.placeholder} />\n <Button colorScheme=\"primary\" disabled={disabled || loading}>\n {loading ? <LoadingCircular /> : <Text>{t.continue}</Text>}\n </Button>\n </>}\n {ssoLoginEnabled && idpLoginEnabled && <p className=\"separator\">{t.or}</p>}\n {idpLoginEnabled &&\n <Button colorScheme=\"light\" type=\"button\" onClick={() => login('idp')} disabled={loading}>\n {loading ? <LoadingCircular /> : (\n <>\n <IconBox>\n <Github />\n </IconBox>\n <Text>{t.loginWithGithub}</Text>\n </>\n )}\n </Button>}\n {error && <Text className=\"error\">{t.error}: {error}</Text>}\n </LoginBox>\n {banner ? <BannerWarning>\n {banner}\n </BannerWarning> : null}\n </>\n )\n}\n\nconst dictionary = {\n en: {\n welcome: 'Welcome to StackSpot',\n placeholder: 'your@email.com',\n continue: 'Continue',\n or: 'or',\n loginWithGithub: 'Login with Github',\n error: 'Error while attempting to login',\n },\n pt: {\n welcome: 'Bem vindo à StackSpot',\n placeholder: 'nome@email.com',\n continue: 'Continuar',\n or: 'ou',\n loginWithGithub: 'Logar com o GitHub',\n error: 'Erro ao fazer login',\n },\n} satisfies Dictionary\n","import { ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { getCookie, getCookieDomain, removeCookie, setCookie } from '@stack-spot/portal-components'\n\nconst sessionKey = `stk-session${getCookieDomain()}`\n\ntype SessionCookie = ThirdPartyLoginParams & { sub: string }\n\nexport const sessionCookie = Object.freeze({\n set: (data: SessionCookie) => setCookie(sessionKey, JSON.stringify(data)),\n get: (): SessionCookie | undefined => {\n try {\n const cookie = getCookie(sessionKey)\n return cookie ? JSON.parse(cookie) : undefined\n } catch (error) {\n console.error(error)\n }\n },\n delete: () => removeCookie(sessionKey)\n})\n","export const redirect = async (url: string) => {\n window.location.href = url\n /**\n * This is intentional. The promise bellow will never be fulfilled.\n * Once the set href is not instantaneous, this will guarantee no further code is executed until the user is really redirected.\n * Particularly useful to prevent flickering page renders on scenarios with redirects.\n */\n await new Promise(() => '')\n}","import { AuthConfig, AuthManager, Session, ThirdPartyAuthType, ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { sessionCookie } from './utils/cookies'\nimport { redirect } from './utils/redirect'\n\nconst sessionKey = 'session'\n\ninterface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant' | 'redirectUrl'> {\n loginUrl: string,\n blockedAuthTypes?: ThirdPartyAuthType[]\n rdUrl?: string,\n}\n\ntype AuthExtraData = { from?: string | null, finalRedirect?: string | null }\n\ntype ChangeListener = (session: Session | undefined) => void\n\n/**\n * Controls the current session in a browser.\n * \n * This should not be used under a Node.JS environment.\n * \n * This is a singleton. To create the first instance or recover the current one, use `SessionManager.create`.\n */\nexport class SessionManager {\n private current: Session | undefined\n private readonly auth: AuthManager<AuthExtraData>\n private config: SessionManagerConfig\n private changeListeners: ChangeListener[] = []\n static instance: SessionManager | undefined\n\n private constructor(config: SessionManagerConfig) {\n this.config = config\n this.auth = new AuthManager<AuthExtraData>({\n ...config,\n storage: localStorage,\n sessionPersistence: {\n load: () => localStorage.getItem(sessionKey),\n save: (session) => localStorage.setItem(sessionKey, session),\n },\n })\n SessionManager.instance = this\n\n // Keep session in sync with other app's session\n addEventListener('focus', () => this.validateSharedSession())\n }\n\n static create(config: SessionManagerConfig) {\n return SessionManager.instance ?? new SessionManager(config)\n }\n\n private setSession(session: Session | undefined) {\n this.current = session\n this.changeListeners.forEach(l => l(session))\n if (session) this.setSessionCookie(session)\n }\n\n async restoreSession() {\n const session = await this.auth.restoreSession()\n const sessionValid = await this.validateSharedSession(session)\n this.setSession(sessionValid ? session : undefined)\n }\n\n async validateSharedSession(session: Session | undefined = this.current): Promise<boolean> {\n\n // skipping because authentication is in progress\n if (this.urlHasThirdPartyLoginData()) return false\n\n const sharedSessionCookie = sessionCookie.get()\n\n // It has been logged out on another portal, so logout on this one too\n if (!sharedSessionCookie) {\n session && await this.logout()\n return false\n }\n\n const isDifferentSessionActive = sharedSessionCookie.sub != session?.getTokenData().sub\n const isSharedSessionTypeBlocked = this.config.blockedAuthTypes?.includes(sharedSessionCookie.type)\n if (isSharedSessionTypeBlocked) return false\n else if (isDifferentSessionActive || !session) {\n await this.startThirdPartyLogin(sharedSessionCookie)\n return false\n }\n return true\n }\n\n hasSession() {\n return !!this.current && !this.current.isExpired()\n }\n\n getSession() {\n if (!this.hasSession()) {\n this.endSession()\n throw new Error('Session is not available, redirecting to login.')\n }\n return this.current!\n }\n\n async endSession(redirectToLogin = true) {\n this.current = undefined\n localStorage.removeItem(sessionKey)\n sessionCookie.delete()\n if (redirectToLogin) await redirect(this.config.loginUrl)\n }\n\n async logout() {\n try {\n await this.current?.logout()\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Could not logout from IDM.\\n${error}`)\n }\n await this.endSession()\n }\n\n async startThirdPartyLogin(data: ThirdPartyLoginParams) {\n const params = new URLSearchParams(location.search)\n const authUrl = await this.auth.startThirdPartyLogin(data, {\n from: location.href,\n finalRedirect: params.get('finalRedirect'),\n })\n await redirect(authUrl)\n }\n\n urlHasThirdPartyLoginData() {\n const url = new URL(location.toString())\n return url.searchParams.has('state') && !url.searchParams.has('error')\n }\n\n async completeThirdPartyLogin() {\n const url = new URL(location.toString())\n if (url.searchParams.has('error')) {\n throw new Error(`Error while signing in: ${url.searchParams.get('error_description')}`)\n }\n const { session, data: { from, finalRedirect } } = await this.auth.completeThirdPartyLogin(location.search)\n this.setSession(session)\n history.replaceState(null, '', from || location.toString().replace(/\\?.*$/, ''))\n this.sendLoginEventRd(this.current?.getTokenData().email, this.current?.getTokenData().name)\n if (finalRedirect) await redirect(finalRedirect)\n }\n\n getEmailForLogin() {\n const session = sessionCookie.get()\n return session?.type == 'sso' ? session.email : undefined\n }\n\n async switchAccount(accountId: string) {\n this.current && await this.auth.switchAccount(accountId, this.current)\n this.setSession(this.current)\n }\n\n onChange(listener: ChangeListener) {\n this.changeListeners.push(listener)\n return () => {\n const index = this.changeListeners.indexOf(listener)\n if (index != -1) this.changeListeners.splice(index, 1)\n }\n }\n\n private setSessionCookie(session: Session) {\n const { email, account_type, sub } = session.getTokenData()\n if (!email || !sub) return\n const isFreemium = account_type == 'FREEMIUM'\n if (isFreemium) {\n sessionCookie.set({ type: 'idp', provider: 'external-idp:github', sub })\n } else {\n sessionCookie.set({ email, type: 'sso', sub })\n }\n }\n\n private async sendLoginEventRd(email?: string, name?: string) {\n if (!this.config.rdUrl) return\n if (!email && !name) {\n // eslint-disable-next-line no-console\n console.error('Unable to trigger login hook. No sessionEmail or name identified.')\n return\n }\n\n const rdObject = {\n event_type: 'CONVERSION',\n event_family: 'CDP',\n payload: {\n email,\n name,\n conversion_identifier: 'login-v1',\n },\n }\n\n const response = await fetch(this.config.rdUrl, {\n method: 'POST',\n body: JSON.stringify(rdObject),\n headers: {\n 'content-type': 'application/json',\n },\n })\n const data = await response.json()\n\n if (!response.ok) {\n // eslint-disable-next-line no-console\n console.error('Error while sending event to RD Station', data)\n }\n }\n}\n","/* eslint-disable max-len */\nimport { Flex } from '@citric/core'\nimport { useEffectOnce } from '@stack-spot/portal-components'\nimport { CSSToCitricAdapter } from '@stack-spot/portal-theme'\nimport '@stack-spot/portal-theme/dist/theme.css'\nimport { useLanguage } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { Login, LoginProps } from './Login'\nimport { SessionManager } from './SessionManager'\n\ntype AuthStatus = 'unknown' | 'authenticated' | 'unauthenticated'\n\ninterface Props {\n children: React.ReactElement,\n onLogin?: () => void,\n onSession?: () => void,\n onChangeStatus?: (status: AuthStatus) => void,\n customLoginProps?: Omit<LoginProps, 'onSubmit' | 'initialValue'>,\n sessionManager?: SessionManager,\n}\n\nexport const Authenticated = ({ children, onLogin, onSession, customLoginProps, sessionManager, onChangeStatus }: Props) => {\n const [authStatus, setAuthStatus] = useState<AuthStatus>('unknown')\n const language = useLanguage()\n sessionManager ??= SessionManager.instance\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n\n useEffectOnce(() => {\n async function checkAuth() {\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n await sessionManager.restoreSession()\n if (sessionManager.urlHasThirdPartyLoginData()) {\n await sessionManager.completeThirdPartyLogin()\n onLogin?.()\n }\n if (sessionManager.hasSession()) {\n setAuthStatus('authenticated')\n onSession?.()\n onChangeStatus?.('authenticated')\n } else {\n setAuthStatus('unauthenticated')\n onChangeStatus?.('unauthenticated')\n }\n }\n\n checkAuth()\n })\n\n if (authStatus === 'unknown') return null\n if (authStatus === 'authenticated') return children\n\n return (\n <CSSToCitricAdapter>\n <Flex justifyContent=\"center\" alignItems=\"center\" flex={1} style={{ height: '100%' }}>\n <Login\n style={{ width: '360px' }}\n onSubmit={data => sessionManager.startThirdPartyLogin({ ...data, locale: language })}\n initialValue={sessionManager.getEmailForLogin()}\n {...(customLoginProps || {})}\n />\n </Flex>\n </CSSToCitricAdapter>\n )\n}\n","import { Session } from '@stack-spot/auth'\nimport { useEffect, useState } from 'react'\nimport { SessionManager } from './SessionManager'\n\nexport function useSession() {\n const manager = SessionManager.instance\n const [session, setSession] = useState<Session | undefined>(manager?.hasSession() ? manager.getSession() : undefined)\n useEffect(() => {\n return manager?.onChange(setSession)\n }, [])\n return session\n}\n"],"names":["styled","theme","useTranslate","useState","error","jsxs","Fragment","jsx","MiniLogo","Text","Input","Button","LoadingCircular","IconBox","Github","BannerWarning","sessionKey","getCookieDomain","setCookie","getCookie","removeCookie","AuthManager","__spreadProps","__spreadValues","useLanguage","useEffectOnce","CSSToCitricAdapter","Flex","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/Login.tsx","../src/utils/cookies.ts","../src/utils/redirect.ts","../src/SessionManager.ts","../src/Authenticated.tsx","../src/hooks.ts"],"sourcesContent":["/* eslint-disable max-len */\nimport { Button, IconBox, Input, Text } from '@citric/core'\nimport { Github } from '@citric/icons'\nimport { LoadingCircular } from '@citric/ui'\nimport { BannerWarning } from '@stack-spot/portal-components'\nimport { MiniLogo } from '@stack-spot/portal-components/svg'\nimport { theme } from '@stack-spot/portal-theme'\nimport { Dictionary, useTranslate } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { styled } from 'styled-components'\n\nexport type LoginType = 'sso' | 'idp'\n\ninterface BaseData {\n type: LoginType,\n}\n\ninterface SSOData extends BaseData {\n type: 'sso',\n email: string,\n}\n\ninterface IDPData extends BaseData {\n type: 'idp',\n provider: 'external-idp:github',\n}\n\ntype LoginData = SSOData | IDPData\n\nexport type LoginProps = {\n initialValue?: string,\n onSubmit: (data: LoginData) => Promise<void>,\n welcomeText?: string,\n removeLoadingOnSuccess?: boolean,\n className?: string,\n style?: React.CSSProperties,\n banner?: React.ReactNode,\n loginTypes?: LoginType[]\n}\n\nconst LoginBox = styled.form`\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 24px;\n\n header {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n }\n\n .title {\n font-size: 1rem;\n }\n\n .separator {\n padding: 0 8px;\n background-color: ${theme.color.light['300']};\n color: ${theme.color.light['700']};\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 20px;\n margin: 0;\n\n &:before, &:after {\n content: '';\n height: 1px;\n flex: 1;\n background-color: ${theme.color.light['600']};\n }\n }\n\n .error {\n color: ${theme.color.danger['500']};\n line-height: 1.5rem;\n }\n`\n\nexport const Login = ({ onSubmit, initialValue = '', welcomeText, removeLoadingOnSuccess, className, style, banner, loginTypes = ['idp', 'sso'] }: LoginProps) => {\n const t = useTranslate(dictionary)\n const searchParams = new URLSearchParams(location.search)\n const [error, setError] = useState(searchParams.get('error_description') || searchParams.get('error') || '')\n const [loading, setLoading] = useState(false)\n const [email, setEmail] = useState(initialValue)\n const disabled = !email.match(/\\w+@\\w+/)\n const idpLoginEnabled = loginTypes.includes('idp')\n const ssoLoginEnabled = loginTypes.includes('sso')\n\n async function login(type: LoginType) {\n setError('')\n setLoading(true)\n try {\n const data: LoginData = type === 'sso' ? { type: 'sso', email } : { type: 'idp', provider: 'external-idp:github' }\n await onSubmit(data)\n if (removeLoadingOnSuccess) setLoading(false)\n } catch (error: any) {\n setLoading(false)\n setError(error.message || error.toString())\n }\n }\n\n function submitForm(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n if (disabled) return\n login('sso')\n }\n\n return (\n <>\n <LoginBox onSubmit={submitForm} className={className} style={style}>\n <header>\n <MiniLogo />\n <Text className=\"title\">{welcomeText || t.welcome}</Text>\n </header>\n {ssoLoginEnabled && <>\n <Input name=\"email\" value={email} onChange={e => setEmail(e.target.value)} placeholder={t.placeholder} />\n <Button colorScheme=\"primary\" disabled={disabled || loading}>\n {loading ? <LoadingCircular /> : <Text>{t.continue}</Text>}\n </Button>\n </>}\n {ssoLoginEnabled && idpLoginEnabled && <p className=\"separator\">{t.or}</p>}\n {idpLoginEnabled &&\n <Button colorScheme=\"light\" type=\"button\" onClick={() => login('idp')} disabled={loading}>\n {loading ? <LoadingCircular /> : (\n <>\n <IconBox>\n <Github />\n </IconBox>\n <Text>{t.loginWithGithub}</Text>\n </>\n )}\n </Button>}\n {error && <Text className=\"error\">{t.error}: {error}</Text>}\n </LoginBox>\n {banner ? <BannerWarning>\n {banner}\n </BannerWarning> : null}\n </>\n )\n}\n\nconst dictionary = {\n en: {\n welcome: 'Welcome to StackSpot',\n placeholder: 'your@email.com',\n continue: 'Continue',\n or: 'or',\n loginWithGithub: 'Login with Github',\n error: 'Error while attempting to login',\n },\n pt: {\n welcome: 'Bem vindo à StackSpot',\n placeholder: 'nome@email.com',\n continue: 'Continuar',\n or: 'ou',\n loginWithGithub: 'Logar com o GitHub',\n error: 'Erro ao fazer login',\n },\n} satisfies Dictionary\n","import { ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { getCookie, getCookieDomain, removeCookie, setCookie } from '@stack-spot/portal-components'\n\nconst sessionKey = `stk-session${getCookieDomain()}`\n\ntype SessionCookie = ThirdPartyLoginParams & { sub: string }\n\nexport const sessionCookie = Object.freeze({\n set: (data: SessionCookie) => setCookie(sessionKey, JSON.stringify(data)),\n get: (): SessionCookie | undefined => {\n try {\n const cookie = getCookie(sessionKey)\n return cookie ? JSON.parse(cookie) : undefined\n } catch (error) {\n console.error(error)\n }\n },\n delete: () => removeCookie(sessionKey)\n})\n","export const redirect = async (url: string) => {\n window.location.href = url\n /**\n * This is intentional. The promise bellow will never be fulfilled.\n * Once the set href is not instantaneous, this will guarantee no further code is executed until the user is really redirected.\n * Particularly useful to prevent flickering page renders on scenarios with redirects.\n */\n await new Promise(() => '')\n}","import { AuthConfig, AuthManager, Session, ThirdPartyAuthType, ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { sessionCookie } from './utils/cookies'\nimport { redirect } from './utils/redirect'\n\nconst sessionKey = 'session'\n\ninterface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant'> {\n /**\n * The URL to redirect to when the user logs out.\n * @default location.origin\n */\n loginUrl?: string,\n /**\n * The URL to redirect to when the login completes in the authentication app. If not provided, will be the same as `loginUrl`.\n * @default loginUrl\n */\n redirectUrl?: string,\n /**\n * Forbidden authentication types to this Session Manager.\n */\n blockedAuthTypes?: ThirdPartyAuthType[]\n /**\n * A URL to send login events to (observability).\n */\n rdUrl?: string,\n}\n\ntype AuthExtraData = { from?: string | null, finalRedirect?: string | null }\n\ntype ChangeListener = (session: Session | undefined) => void\n\n/**\n * Controls the current session in a browser.\n * \n * This should not be used under a Node.JS environment.\n * \n * This is a singleton. To create the first instance or recover the current one, use `SessionManager.create`.\n */\nexport class SessionManager {\n private current: Session | undefined\n private readonly auth: AuthManager<AuthExtraData>\n private config: SessionManagerConfig\n private changeListeners: ChangeListener[] = []\n static instance: SessionManager | undefined\n\n private constructor(config: SessionManagerConfig) {\n config.loginUrl ||= location.origin\n const redirectUrl = (config.redirectUrl || config.loginUrl).replace(/([^/])$/, '$1/') // the trailing \"/\" is required by Stackspot IAM.\n this.config = config\n this.auth = new AuthManager<AuthExtraData>({\n ...config,\n redirectUrl,\n storage: localStorage,\n sessionPersistence: {\n load: () => localStorage.getItem(sessionKey),\n save: (session) => localStorage.setItem(sessionKey, session),\n },\n })\n SessionManager.instance = this\n\n // Keep session in sync with other app's session\n addEventListener('focus', () => this.validateSharedSession())\n }\n\n static create(config: SessionManagerConfig) {\n return SessionManager.instance ?? new SessionManager(config)\n }\n\n private setSession(session: Session | undefined) {\n this.current = session\n this.changeListeners.forEach(l => l(session))\n if (session) this.setSessionCookie(session)\n }\n\n async restoreSession() {\n const session = await this.auth.restoreSession()\n const sessionValid = await this.validateSharedSession(session)\n this.setSession(sessionValid ? session : undefined)\n }\n\n async validateSharedSession(session: Session | undefined = this.current): Promise<boolean> {\n\n // skipping because authentication is in progress\n if (this.urlHasThirdPartyLoginData()) return false\n\n const sharedSessionCookie = sessionCookie.get()\n\n // It has been logged out on another portal, so logout on this one too\n if (!sharedSessionCookie) {\n session && await this.logout()\n return false\n }\n\n const isDifferentSessionActive = sharedSessionCookie.sub != session?.getTokenData().sub\n const isSharedSessionTypeBlocked = this.config.blockedAuthTypes?.includes(sharedSessionCookie.type)\n if (isSharedSessionTypeBlocked) return false\n else if (isDifferentSessionActive || !session) {\n await this.startThirdPartyLogin(sharedSessionCookie)\n return false\n }\n return true\n }\n\n hasSession() {\n return !!this.current && !this.current.isExpired()\n }\n\n getSession() {\n if (!this.hasSession()) {\n this.endSession()\n throw new Error('Session is not available, redirecting to login.')\n }\n return this.current!\n }\n\n async endSession(redirectToLogin = true) {\n this.current = undefined\n localStorage.removeItem(sessionKey)\n sessionCookie.delete()\n if (redirectToLogin && this.config.loginUrl) await redirect(this.config.loginUrl)\n }\n\n async logout() {\n try {\n await this.current?.logout()\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Could not logout from IDM.\\n${error}`)\n }\n await this.endSession()\n }\n\n async startThirdPartyLogin(data: ThirdPartyLoginParams) {\n const params = new URLSearchParams(location.search)\n const authUrl = await this.auth.startThirdPartyLogin(data, {\n from: location.href,\n finalRedirect: params.get('finalRedirect'),\n })\n await redirect(authUrl)\n }\n\n urlHasThirdPartyLoginData() {\n const url = new URL(location.toString())\n return url.searchParams.has('state') && !url.searchParams.has('error')\n }\n\n async completeThirdPartyLogin() {\n const url = new URL(location.toString())\n if (url.searchParams.has('error')) {\n throw new Error(`Error while signing in: ${url.searchParams.get('error_description')}`)\n }\n const { session, data: { from, finalRedirect } } = await this.auth.completeThirdPartyLogin(location.search)\n this.setSession(session)\n history.replaceState(null, '', from || location.toString().replace(/\\?.*$/, ''))\n this.sendLoginEventRd(this.current?.getTokenData().email, this.current?.getTokenData().name)\n if (finalRedirect) await redirect(finalRedirect)\n }\n\n getEmailForLogin() {\n const session = sessionCookie.get()\n return session?.type == 'sso' ? session.email : undefined\n }\n\n async switchAccount(accountId: string) {\n this.current && await this.auth.switchAccount(accountId, this.current)\n this.setSession(this.current)\n }\n\n onChange(listener: ChangeListener) {\n this.changeListeners.push(listener)\n return () => {\n const index = this.changeListeners.indexOf(listener)\n if (index != -1) this.changeListeners.splice(index, 1)\n }\n }\n\n private setSessionCookie(session: Session) {\n const { email, account_type, sub } = session.getTokenData()\n if (!email || !sub) return\n const isFreemium = account_type == 'FREEMIUM'\n if (isFreemium) {\n sessionCookie.set({ type: 'idp', provider: 'external-idp:github', sub })\n } else {\n sessionCookie.set({ email, type: 'sso', sub })\n }\n }\n\n private async sendLoginEventRd(email?: string, name?: string) {\n if (!this.config.rdUrl) return\n if (!email && !name) {\n // eslint-disable-next-line no-console\n console.error('Unable to trigger login hook. No sessionEmail or name identified.')\n return\n }\n\n const rdObject = {\n event_type: 'CONVERSION',\n event_family: 'CDP',\n payload: {\n email,\n name,\n conversion_identifier: 'login-v1',\n },\n }\n\n const response = await fetch(this.config.rdUrl, {\n method: 'POST',\n body: JSON.stringify(rdObject),\n headers: {\n 'content-type': 'application/json',\n },\n })\n const data = await response.json()\n\n if (!response.ok) {\n // eslint-disable-next-line no-console\n console.error('Error while sending event to RD Station', data)\n }\n }\n}\n","/* eslint-disable max-len */\nimport { Flex } from '@citric/core'\nimport { useEffectOnce } from '@stack-spot/portal-components'\nimport { CSSToCitricAdapter } from '@stack-spot/portal-theme'\nimport '@stack-spot/portal-theme/dist/theme.css'\nimport { useLanguage } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { Login, LoginProps } from './Login'\nimport { SessionManager } from './SessionManager'\n\ntype AuthStatus = 'unknown' | 'authenticated' | 'unauthenticated'\n\ninterface Props {\n children: React.ReactElement,\n onLogin?: () => void,\n onSession?: () => void,\n onChangeStatus?: (status: AuthStatus) => void,\n customLoginProps?: Omit<LoginProps, 'onSubmit' | 'initialValue'>,\n sessionManager?: SessionManager,\n}\n\nexport const Authenticated = ({ children, onLogin, onSession, customLoginProps, sessionManager, onChangeStatus }: Props) => {\n const [authStatus, setAuthStatus] = useState<AuthStatus>('unknown')\n const language = useLanguage()\n sessionManager ??= SessionManager.instance\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n\n useEffectOnce(() => {\n async function checkAuth() {\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n await sessionManager.restoreSession()\n if (sessionManager.urlHasThirdPartyLoginData()) {\n await sessionManager.completeThirdPartyLogin()\n onLogin?.()\n }\n if (sessionManager.hasSession()) {\n setAuthStatus('authenticated')\n onSession?.()\n onChangeStatus?.('authenticated')\n } else {\n setAuthStatus('unauthenticated')\n onChangeStatus?.('unauthenticated')\n }\n }\n\n checkAuth()\n })\n\n if (authStatus === 'unknown') return null\n if (authStatus === 'authenticated') return children\n\n return (\n <CSSToCitricAdapter>\n <Flex justifyContent=\"center\" alignItems=\"center\" flex={1} style={{ height: '100%' }}>\n <Login\n style={{ width: '360px' }}\n onSubmit={data => sessionManager.startThirdPartyLogin({ ...data, locale: language })}\n initialValue={sessionManager.getEmailForLogin()}\n {...(customLoginProps || {})}\n />\n </Flex>\n </CSSToCitricAdapter>\n )\n}\n","import { Session } from '@stack-spot/auth'\nimport { useEffect, useState } from 'react'\nimport { SessionManager } from './SessionManager'\n\nexport function useSession() {\n const manager = SessionManager.instance\n const [session, setSession] = useState<Session | undefined>(manager?.hasSession() ? manager.getSession() : undefined)\n useEffect(() => {\n return manager?.onChange(setSession)\n }, [])\n return session\n}\n"],"names":["styled","theme","useTranslate","useState","error","jsxs","Fragment","jsx","MiniLogo","Text","Input","Button","LoadingCircular","IconBox","Github","BannerWarning","sessionKey","getCookieDomain","setCookie","getCookie","removeCookie","AuthManager","__spreadProps","__spreadValues","useLanguage","useEffectOnce","CSSToCitricAdapter","Flex","useEffect"],"mappings":"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"}
package/out/index.mjs CHANGED
@@ -30,7 +30,7 @@ const LoginBox = styled.form`
30
30
 
31
31
  .separator {
32
32
  padding: 0 8px;
33
- background-color: ${theme.color.light["400"]};
33
+ background-color: ${theme.color.light["300"]};
34
34
  color: ${theme.color.light["700"]};
35
35
  display: flex;
36
36
  flex-direction: row;
@@ -172,8 +172,11 @@ const _SessionManager = class _SessionManager {
172
172
  __publicField(this, "auth");
173
173
  __publicField(this, "config");
174
174
  __publicField(this, "changeListeners", []);
175
+ config.loginUrl || (config.loginUrl = location.origin);
176
+ const redirectUrl = (config.redirectUrl || config.loginUrl).replace(/([^/])$/, "$1/");
175
177
  this.config = config;
176
178
  this.auth = new AuthManager(__spreadProps$1(__spreadValues$1({}, config), {
179
+ redirectUrl,
177
180
  storage: localStorage,
178
181
  sessionPersistence: {
179
182
  load: () => localStorage.getItem(sessionKey),
@@ -231,7 +234,7 @@ const _SessionManager = class _SessionManager {
231
234
  this.current = void 0;
232
235
  localStorage.removeItem(sessionKey);
233
236
  sessionCookie.delete();
234
- if (redirectToLogin)
237
+ if (redirectToLogin && this.config.loginUrl)
235
238
  await redirect(this.config.loginUrl);
236
239
  }
237
240
  async logout() {
package/out/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/Login.tsx","../src/utils/cookies.ts","../src/utils/redirect.ts","../src/SessionManager.ts","../src/Authenticated.tsx","../src/hooks.ts"],"sourcesContent":["/* eslint-disable max-len */\nimport { Button, IconBox, Input, Text } from '@citric/core'\nimport { Github } from '@citric/icons'\nimport { LoadingCircular } from '@citric/ui'\nimport { BannerWarning } from '@stack-spot/portal-components'\nimport { MiniLogo } from '@stack-spot/portal-components/svg'\nimport { theme } from '@stack-spot/portal-theme'\nimport { Dictionary, useTranslate } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { styled } from 'styled-components'\n\nexport type LoginType = 'sso' | 'idp'\n\ninterface BaseData {\n type: LoginType,\n}\n\ninterface SSOData extends BaseData {\n type: 'sso',\n email: string,\n}\n\ninterface IDPData extends BaseData {\n type: 'idp',\n provider: 'external-idp:github',\n}\n\ntype LoginData = SSOData | IDPData\n\nexport type LoginProps = {\n initialValue?: string,\n onSubmit: (data: LoginData) => Promise<void>,\n welcomeText?: string,\n removeLoadingOnSuccess?: boolean,\n className?: string,\n style?: React.CSSProperties,\n banner?: React.ReactNode,\n loginTypes?: LoginType[]\n}\n\nconst LoginBox = styled.form`\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 24px;\n\n header {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n }\n\n .title {\n font-size: 1rem;\n }\n\n .separator {\n padding: 0 8px;\n background-color: ${theme.color.light['400']};\n color: ${theme.color.light['700']};\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 20px;\n margin: 0;\n\n &:before, &:after {\n content: '';\n height: 1px;\n flex: 1;\n background-color: ${theme.color.light['600']};\n }\n }\n\n .error {\n color: ${theme.color.danger['500']};\n line-height: 1.5rem;\n }\n`\n\nexport const Login = ({ onSubmit, initialValue = '', welcomeText, removeLoadingOnSuccess, className, style, banner, loginTypes = ['idp', 'sso'] }: LoginProps) => {\n const t = useTranslate(dictionary)\n const searchParams = new URLSearchParams(location.search)\n const [error, setError] = useState(searchParams.get('error_description') || searchParams.get('error') || '')\n const [loading, setLoading] = useState(false)\n const [email, setEmail] = useState(initialValue)\n const disabled = !email.match(/\\w+@\\w+/)\n const idpLoginEnabled = loginTypes.includes('idp')\n const ssoLoginEnabled = loginTypes.includes('sso')\n\n async function login(type: LoginType) {\n setError('')\n setLoading(true)\n try {\n const data: LoginData = type === 'sso' ? { type: 'sso', email } : { type: 'idp', provider: 'external-idp:github' }\n await onSubmit(data)\n if (removeLoadingOnSuccess) setLoading(false)\n } catch (error: any) {\n setLoading(false)\n setError(error.message || error.toString())\n }\n }\n\n function submitForm(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n if (disabled) return\n login('sso')\n }\n\n return (\n <>\n <LoginBox onSubmit={submitForm} className={className} style={style}>\n <header>\n <MiniLogo />\n <Text className=\"title\">{welcomeText || t.welcome}</Text>\n </header>\n {ssoLoginEnabled && <>\n <Input name=\"email\" value={email} onChange={e => setEmail(e.target.value)} placeholder={t.placeholder} />\n <Button colorScheme=\"primary\" disabled={disabled || loading}>\n {loading ? <LoadingCircular /> : <Text>{t.continue}</Text>}\n </Button>\n </>}\n {ssoLoginEnabled && idpLoginEnabled && <p className=\"separator\">{t.or}</p>}\n {idpLoginEnabled &&\n <Button colorScheme=\"light\" type=\"button\" onClick={() => login('idp')} disabled={loading}>\n {loading ? <LoadingCircular /> : (\n <>\n <IconBox>\n <Github />\n </IconBox>\n <Text>{t.loginWithGithub}</Text>\n </>\n )}\n </Button>}\n {error && <Text className=\"error\">{t.error}: {error}</Text>}\n </LoginBox>\n {banner ? <BannerWarning>\n {banner}\n </BannerWarning> : null}\n </>\n )\n}\n\nconst dictionary = {\n en: {\n welcome: 'Welcome to StackSpot',\n placeholder: 'your@email.com',\n continue: 'Continue',\n or: 'or',\n loginWithGithub: 'Login with Github',\n error: 'Error while attempting to login',\n },\n pt: {\n welcome: 'Bem vindo à StackSpot',\n placeholder: 'nome@email.com',\n continue: 'Continuar',\n or: 'ou',\n loginWithGithub: 'Logar com o GitHub',\n error: 'Erro ao fazer login',\n },\n} satisfies Dictionary\n","import { ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { getCookie, getCookieDomain, removeCookie, setCookie } from '@stack-spot/portal-components'\n\nconst sessionKey = `stk-session${getCookieDomain()}`\n\ntype SessionCookie = ThirdPartyLoginParams & { sub: string }\n\nexport const sessionCookie = Object.freeze({\n set: (data: SessionCookie) => setCookie(sessionKey, JSON.stringify(data)),\n get: (): SessionCookie | undefined => {\n try {\n const cookie = getCookie(sessionKey)\n return cookie ? JSON.parse(cookie) : undefined\n } catch (error) {\n console.error(error)\n }\n },\n delete: () => removeCookie(sessionKey)\n})\n","export const redirect = async (url: string) => {\n window.location.href = url\n /**\n * This is intentional. The promise bellow will never be fulfilled.\n * Once the set href is not instantaneous, this will guarantee no further code is executed until the user is really redirected.\n * Particularly useful to prevent flickering page renders on scenarios with redirects.\n */\n await new Promise(() => '')\n}","import { AuthConfig, AuthManager, Session, ThirdPartyAuthType, ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { sessionCookie } from './utils/cookies'\nimport { redirect } from './utils/redirect'\n\nconst sessionKey = 'session'\n\ninterface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant' | 'redirectUrl'> {\n loginUrl: string,\n blockedAuthTypes?: ThirdPartyAuthType[]\n rdUrl?: string,\n}\n\ntype AuthExtraData = { from?: string | null, finalRedirect?: string | null }\n\ntype ChangeListener = (session: Session | undefined) => void\n\n/**\n * Controls the current session in a browser.\n * \n * This should not be used under a Node.JS environment.\n * \n * This is a singleton. To create the first instance or recover the current one, use `SessionManager.create`.\n */\nexport class SessionManager {\n private current: Session | undefined\n private readonly auth: AuthManager<AuthExtraData>\n private config: SessionManagerConfig\n private changeListeners: ChangeListener[] = []\n static instance: SessionManager | undefined\n\n private constructor(config: SessionManagerConfig) {\n this.config = config\n this.auth = new AuthManager<AuthExtraData>({\n ...config,\n storage: localStorage,\n sessionPersistence: {\n load: () => localStorage.getItem(sessionKey),\n save: (session) => localStorage.setItem(sessionKey, session),\n },\n })\n SessionManager.instance = this\n\n // Keep session in sync with other app's session\n addEventListener('focus', () => this.validateSharedSession())\n }\n\n static create(config: SessionManagerConfig) {\n return SessionManager.instance ?? new SessionManager(config)\n }\n\n private setSession(session: Session | undefined) {\n this.current = session\n this.changeListeners.forEach(l => l(session))\n if (session) this.setSessionCookie(session)\n }\n\n async restoreSession() {\n const session = await this.auth.restoreSession()\n const sessionValid = await this.validateSharedSession(session)\n this.setSession(sessionValid ? session : undefined)\n }\n\n async validateSharedSession(session: Session | undefined = this.current): Promise<boolean> {\n\n // skipping because authentication is in progress\n if (this.urlHasThirdPartyLoginData()) return false\n\n const sharedSessionCookie = sessionCookie.get()\n\n // It has been logged out on another portal, so logout on this one too\n if (!sharedSessionCookie) {\n session && await this.logout()\n return false\n }\n\n const isDifferentSessionActive = sharedSessionCookie.sub != session?.getTokenData().sub\n const isSharedSessionTypeBlocked = this.config.blockedAuthTypes?.includes(sharedSessionCookie.type)\n if (isSharedSessionTypeBlocked) return false\n else if (isDifferentSessionActive || !session) {\n await this.startThirdPartyLogin(sharedSessionCookie)\n return false\n }\n return true\n }\n\n hasSession() {\n return !!this.current && !this.current.isExpired()\n }\n\n getSession() {\n if (!this.hasSession()) {\n this.endSession()\n throw new Error('Session is not available, redirecting to login.')\n }\n return this.current!\n }\n\n async endSession(redirectToLogin = true) {\n this.current = undefined\n localStorage.removeItem(sessionKey)\n sessionCookie.delete()\n if (redirectToLogin) await redirect(this.config.loginUrl)\n }\n\n async logout() {\n try {\n await this.current?.logout()\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Could not logout from IDM.\\n${error}`)\n }\n await this.endSession()\n }\n\n async startThirdPartyLogin(data: ThirdPartyLoginParams) {\n const params = new URLSearchParams(location.search)\n const authUrl = await this.auth.startThirdPartyLogin(data, {\n from: location.href,\n finalRedirect: params.get('finalRedirect'),\n })\n await redirect(authUrl)\n }\n\n urlHasThirdPartyLoginData() {\n const url = new URL(location.toString())\n return url.searchParams.has('state') && !url.searchParams.has('error')\n }\n\n async completeThirdPartyLogin() {\n const url = new URL(location.toString())\n if (url.searchParams.has('error')) {\n throw new Error(`Error while signing in: ${url.searchParams.get('error_description')}`)\n }\n const { session, data: { from, finalRedirect } } = await this.auth.completeThirdPartyLogin(location.search)\n this.setSession(session)\n history.replaceState(null, '', from || location.toString().replace(/\\?.*$/, ''))\n this.sendLoginEventRd(this.current?.getTokenData().email, this.current?.getTokenData().name)\n if (finalRedirect) await redirect(finalRedirect)\n }\n\n getEmailForLogin() {\n const session = sessionCookie.get()\n return session?.type == 'sso' ? session.email : undefined\n }\n\n async switchAccount(accountId: string) {\n this.current && await this.auth.switchAccount(accountId, this.current)\n this.setSession(this.current)\n }\n\n onChange(listener: ChangeListener) {\n this.changeListeners.push(listener)\n return () => {\n const index = this.changeListeners.indexOf(listener)\n if (index != -1) this.changeListeners.splice(index, 1)\n }\n }\n\n private setSessionCookie(session: Session) {\n const { email, account_type, sub } = session.getTokenData()\n if (!email || !sub) return\n const isFreemium = account_type == 'FREEMIUM'\n if (isFreemium) {\n sessionCookie.set({ type: 'idp', provider: 'external-idp:github', sub })\n } else {\n sessionCookie.set({ email, type: 'sso', sub })\n }\n }\n\n private async sendLoginEventRd(email?: string, name?: string) {\n if (!this.config.rdUrl) return\n if (!email && !name) {\n // eslint-disable-next-line no-console\n console.error('Unable to trigger login hook. No sessionEmail or name identified.')\n return\n }\n\n const rdObject = {\n event_type: 'CONVERSION',\n event_family: 'CDP',\n payload: {\n email,\n name,\n conversion_identifier: 'login-v1',\n },\n }\n\n const response = await fetch(this.config.rdUrl, {\n method: 'POST',\n body: JSON.stringify(rdObject),\n headers: {\n 'content-type': 'application/json',\n },\n })\n const data = await response.json()\n\n if (!response.ok) {\n // eslint-disable-next-line no-console\n console.error('Error while sending event to RD Station', data)\n }\n }\n}\n","/* eslint-disable max-len */\nimport { Flex } from '@citric/core'\nimport { useEffectOnce } from '@stack-spot/portal-components'\nimport { CSSToCitricAdapter } from '@stack-spot/portal-theme'\nimport '@stack-spot/portal-theme/dist/theme.css'\nimport { useLanguage } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { Login, LoginProps } from './Login'\nimport { SessionManager } from './SessionManager'\n\ntype AuthStatus = 'unknown' | 'authenticated' | 'unauthenticated'\n\ninterface Props {\n children: React.ReactElement,\n onLogin?: () => void,\n onSession?: () => void,\n onChangeStatus?: (status: AuthStatus) => void,\n customLoginProps?: Omit<LoginProps, 'onSubmit' | 'initialValue'>,\n sessionManager?: SessionManager,\n}\n\nexport const Authenticated = ({ children, onLogin, onSession, customLoginProps, sessionManager, onChangeStatus }: Props) => {\n const [authStatus, setAuthStatus] = useState<AuthStatus>('unknown')\n const language = useLanguage()\n sessionManager ??= SessionManager.instance\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n\n useEffectOnce(() => {\n async function checkAuth() {\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n await sessionManager.restoreSession()\n if (sessionManager.urlHasThirdPartyLoginData()) {\n await sessionManager.completeThirdPartyLogin()\n onLogin?.()\n }\n if (sessionManager.hasSession()) {\n setAuthStatus('authenticated')\n onSession?.()\n onChangeStatus?.('authenticated')\n } else {\n setAuthStatus('unauthenticated')\n onChangeStatus?.('unauthenticated')\n }\n }\n\n checkAuth()\n })\n\n if (authStatus === 'unknown') return null\n if (authStatus === 'authenticated') return children\n\n return (\n <CSSToCitricAdapter>\n <Flex justifyContent=\"center\" alignItems=\"center\" flex={1} style={{ height: '100%' }}>\n <Login\n style={{ width: '360px' }}\n onSubmit={data => sessionManager.startThirdPartyLogin({ ...data, locale: language })}\n initialValue={sessionManager.getEmailForLogin()}\n {...(customLoginProps || {})}\n />\n </Flex>\n </CSSToCitricAdapter>\n )\n}\n","import { Session } from '@stack-spot/auth'\nimport { useEffect, useState } from 'react'\nimport { SessionManager } from './SessionManager'\n\nexport function useSession() {\n const manager = SessionManager.instance\n const [session, setSession] = useState<Session | undefined>(manager?.hasSession() ? manager.getSession() : undefined)\n useEffect(() => {\n return manager?.onChange(setSession)\n }, [])\n return session\n}\n"],"names":["error","sessionKey","__spreadProps","__spreadValues"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/Login.tsx","../src/utils/cookies.ts","../src/utils/redirect.ts","../src/SessionManager.ts","../src/Authenticated.tsx","../src/hooks.ts"],"sourcesContent":["/* eslint-disable max-len */\nimport { Button, IconBox, Input, Text } from '@citric/core'\nimport { Github } from '@citric/icons'\nimport { LoadingCircular } from '@citric/ui'\nimport { BannerWarning } from '@stack-spot/portal-components'\nimport { MiniLogo } from '@stack-spot/portal-components/svg'\nimport { theme } from '@stack-spot/portal-theme'\nimport { Dictionary, useTranslate } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { styled } from 'styled-components'\n\nexport type LoginType = 'sso' | 'idp'\n\ninterface BaseData {\n type: LoginType,\n}\n\ninterface SSOData extends BaseData {\n type: 'sso',\n email: string,\n}\n\ninterface IDPData extends BaseData {\n type: 'idp',\n provider: 'external-idp:github',\n}\n\ntype LoginData = SSOData | IDPData\n\nexport type LoginProps = {\n initialValue?: string,\n onSubmit: (data: LoginData) => Promise<void>,\n welcomeText?: string,\n removeLoadingOnSuccess?: boolean,\n className?: string,\n style?: React.CSSProperties,\n banner?: React.ReactNode,\n loginTypes?: LoginType[]\n}\n\nconst LoginBox = styled.form`\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 24px;\n\n header {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n }\n\n .title {\n font-size: 1rem;\n }\n\n .separator {\n padding: 0 8px;\n background-color: ${theme.color.light['300']};\n color: ${theme.color.light['700']};\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 20px;\n margin: 0;\n\n &:before, &:after {\n content: '';\n height: 1px;\n flex: 1;\n background-color: ${theme.color.light['600']};\n }\n }\n\n .error {\n color: ${theme.color.danger['500']};\n line-height: 1.5rem;\n }\n`\n\nexport const Login = ({ onSubmit, initialValue = '', welcomeText, removeLoadingOnSuccess, className, style, banner, loginTypes = ['idp', 'sso'] }: LoginProps) => {\n const t = useTranslate(dictionary)\n const searchParams = new URLSearchParams(location.search)\n const [error, setError] = useState(searchParams.get('error_description') || searchParams.get('error') || '')\n const [loading, setLoading] = useState(false)\n const [email, setEmail] = useState(initialValue)\n const disabled = !email.match(/\\w+@\\w+/)\n const idpLoginEnabled = loginTypes.includes('idp')\n const ssoLoginEnabled = loginTypes.includes('sso')\n\n async function login(type: LoginType) {\n setError('')\n setLoading(true)\n try {\n const data: LoginData = type === 'sso' ? { type: 'sso', email } : { type: 'idp', provider: 'external-idp:github' }\n await onSubmit(data)\n if (removeLoadingOnSuccess) setLoading(false)\n } catch (error: any) {\n setLoading(false)\n setError(error.message || error.toString())\n }\n }\n\n function submitForm(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n if (disabled) return\n login('sso')\n }\n\n return (\n <>\n <LoginBox onSubmit={submitForm} className={className} style={style}>\n <header>\n <MiniLogo />\n <Text className=\"title\">{welcomeText || t.welcome}</Text>\n </header>\n {ssoLoginEnabled && <>\n <Input name=\"email\" value={email} onChange={e => setEmail(e.target.value)} placeholder={t.placeholder} />\n <Button colorScheme=\"primary\" disabled={disabled || loading}>\n {loading ? <LoadingCircular /> : <Text>{t.continue}</Text>}\n </Button>\n </>}\n {ssoLoginEnabled && idpLoginEnabled && <p className=\"separator\">{t.or}</p>}\n {idpLoginEnabled &&\n <Button colorScheme=\"light\" type=\"button\" onClick={() => login('idp')} disabled={loading}>\n {loading ? <LoadingCircular /> : (\n <>\n <IconBox>\n <Github />\n </IconBox>\n <Text>{t.loginWithGithub}</Text>\n </>\n )}\n </Button>}\n {error && <Text className=\"error\">{t.error}: {error}</Text>}\n </LoginBox>\n {banner ? <BannerWarning>\n {banner}\n </BannerWarning> : null}\n </>\n )\n}\n\nconst dictionary = {\n en: {\n welcome: 'Welcome to StackSpot',\n placeholder: 'your@email.com',\n continue: 'Continue',\n or: 'or',\n loginWithGithub: 'Login with Github',\n error: 'Error while attempting to login',\n },\n pt: {\n welcome: 'Bem vindo à StackSpot',\n placeholder: 'nome@email.com',\n continue: 'Continuar',\n or: 'ou',\n loginWithGithub: 'Logar com o GitHub',\n error: 'Erro ao fazer login',\n },\n} satisfies Dictionary\n","import { ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { getCookie, getCookieDomain, removeCookie, setCookie } from '@stack-spot/portal-components'\n\nconst sessionKey = `stk-session${getCookieDomain()}`\n\ntype SessionCookie = ThirdPartyLoginParams & { sub: string }\n\nexport const sessionCookie = Object.freeze({\n set: (data: SessionCookie) => setCookie(sessionKey, JSON.stringify(data)),\n get: (): SessionCookie | undefined => {\n try {\n const cookie = getCookie(sessionKey)\n return cookie ? JSON.parse(cookie) : undefined\n } catch (error) {\n console.error(error)\n }\n },\n delete: () => removeCookie(sessionKey)\n})\n","export const redirect = async (url: string) => {\n window.location.href = url\n /**\n * This is intentional. The promise bellow will never be fulfilled.\n * Once the set href is not instantaneous, this will guarantee no further code is executed until the user is really redirected.\n * Particularly useful to prevent flickering page renders on scenarios with redirects.\n */\n await new Promise(() => '')\n}","import { AuthConfig, AuthManager, Session, ThirdPartyAuthType, ThirdPartyLoginParams } from '@stack-spot/auth'\nimport { sessionCookie } from './utils/cookies'\nimport { redirect } from './utils/redirect'\n\nconst sessionKey = 'session'\n\ninterface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant'> {\n /**\n * The URL to redirect to when the user logs out.\n * @default location.origin\n */\n loginUrl?: string,\n /**\n * The URL to redirect to when the login completes in the authentication app. If not provided, will be the same as `loginUrl`.\n * @default loginUrl\n */\n redirectUrl?: string,\n /**\n * Forbidden authentication types to this Session Manager.\n */\n blockedAuthTypes?: ThirdPartyAuthType[]\n /**\n * A URL to send login events to (observability).\n */\n rdUrl?: string,\n}\n\ntype AuthExtraData = { from?: string | null, finalRedirect?: string | null }\n\ntype ChangeListener = (session: Session | undefined) => void\n\n/**\n * Controls the current session in a browser.\n * \n * This should not be used under a Node.JS environment.\n * \n * This is a singleton. To create the first instance or recover the current one, use `SessionManager.create`.\n */\nexport class SessionManager {\n private current: Session | undefined\n private readonly auth: AuthManager<AuthExtraData>\n private config: SessionManagerConfig\n private changeListeners: ChangeListener[] = []\n static instance: SessionManager | undefined\n\n private constructor(config: SessionManagerConfig) {\n config.loginUrl ||= location.origin\n const redirectUrl = (config.redirectUrl || config.loginUrl).replace(/([^/])$/, '$1/') // the trailing \"/\" is required by Stackspot IAM.\n this.config = config\n this.auth = new AuthManager<AuthExtraData>({\n ...config,\n redirectUrl,\n storage: localStorage,\n sessionPersistence: {\n load: () => localStorage.getItem(sessionKey),\n save: (session) => localStorage.setItem(sessionKey, session),\n },\n })\n SessionManager.instance = this\n\n // Keep session in sync with other app's session\n addEventListener('focus', () => this.validateSharedSession())\n }\n\n static create(config: SessionManagerConfig) {\n return SessionManager.instance ?? new SessionManager(config)\n }\n\n private setSession(session: Session | undefined) {\n this.current = session\n this.changeListeners.forEach(l => l(session))\n if (session) this.setSessionCookie(session)\n }\n\n async restoreSession() {\n const session = await this.auth.restoreSession()\n const sessionValid = await this.validateSharedSession(session)\n this.setSession(sessionValid ? session : undefined)\n }\n\n async validateSharedSession(session: Session | undefined = this.current): Promise<boolean> {\n\n // skipping because authentication is in progress\n if (this.urlHasThirdPartyLoginData()) return false\n\n const sharedSessionCookie = sessionCookie.get()\n\n // It has been logged out on another portal, so logout on this one too\n if (!sharedSessionCookie) {\n session && await this.logout()\n return false\n }\n\n const isDifferentSessionActive = sharedSessionCookie.sub != session?.getTokenData().sub\n const isSharedSessionTypeBlocked = this.config.blockedAuthTypes?.includes(sharedSessionCookie.type)\n if (isSharedSessionTypeBlocked) return false\n else if (isDifferentSessionActive || !session) {\n await this.startThirdPartyLogin(sharedSessionCookie)\n return false\n }\n return true\n }\n\n hasSession() {\n return !!this.current && !this.current.isExpired()\n }\n\n getSession() {\n if (!this.hasSession()) {\n this.endSession()\n throw new Error('Session is not available, redirecting to login.')\n }\n return this.current!\n }\n\n async endSession(redirectToLogin = true) {\n this.current = undefined\n localStorage.removeItem(sessionKey)\n sessionCookie.delete()\n if (redirectToLogin && this.config.loginUrl) await redirect(this.config.loginUrl)\n }\n\n async logout() {\n try {\n await this.current?.logout()\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Could not logout from IDM.\\n${error}`)\n }\n await this.endSession()\n }\n\n async startThirdPartyLogin(data: ThirdPartyLoginParams) {\n const params = new URLSearchParams(location.search)\n const authUrl = await this.auth.startThirdPartyLogin(data, {\n from: location.href,\n finalRedirect: params.get('finalRedirect'),\n })\n await redirect(authUrl)\n }\n\n urlHasThirdPartyLoginData() {\n const url = new URL(location.toString())\n return url.searchParams.has('state') && !url.searchParams.has('error')\n }\n\n async completeThirdPartyLogin() {\n const url = new URL(location.toString())\n if (url.searchParams.has('error')) {\n throw new Error(`Error while signing in: ${url.searchParams.get('error_description')}`)\n }\n const { session, data: { from, finalRedirect } } = await this.auth.completeThirdPartyLogin(location.search)\n this.setSession(session)\n history.replaceState(null, '', from || location.toString().replace(/\\?.*$/, ''))\n this.sendLoginEventRd(this.current?.getTokenData().email, this.current?.getTokenData().name)\n if (finalRedirect) await redirect(finalRedirect)\n }\n\n getEmailForLogin() {\n const session = sessionCookie.get()\n return session?.type == 'sso' ? session.email : undefined\n }\n\n async switchAccount(accountId: string) {\n this.current && await this.auth.switchAccount(accountId, this.current)\n this.setSession(this.current)\n }\n\n onChange(listener: ChangeListener) {\n this.changeListeners.push(listener)\n return () => {\n const index = this.changeListeners.indexOf(listener)\n if (index != -1) this.changeListeners.splice(index, 1)\n }\n }\n\n private setSessionCookie(session: Session) {\n const { email, account_type, sub } = session.getTokenData()\n if (!email || !sub) return\n const isFreemium = account_type == 'FREEMIUM'\n if (isFreemium) {\n sessionCookie.set({ type: 'idp', provider: 'external-idp:github', sub })\n } else {\n sessionCookie.set({ email, type: 'sso', sub })\n }\n }\n\n private async sendLoginEventRd(email?: string, name?: string) {\n if (!this.config.rdUrl) return\n if (!email && !name) {\n // eslint-disable-next-line no-console\n console.error('Unable to trigger login hook. No sessionEmail or name identified.')\n return\n }\n\n const rdObject = {\n event_type: 'CONVERSION',\n event_family: 'CDP',\n payload: {\n email,\n name,\n conversion_identifier: 'login-v1',\n },\n }\n\n const response = await fetch(this.config.rdUrl, {\n method: 'POST',\n body: JSON.stringify(rdObject),\n headers: {\n 'content-type': 'application/json',\n },\n })\n const data = await response.json()\n\n if (!response.ok) {\n // eslint-disable-next-line no-console\n console.error('Error while sending event to RD Station', data)\n }\n }\n}\n","/* eslint-disable max-len */\nimport { Flex } from '@citric/core'\nimport { useEffectOnce } from '@stack-spot/portal-components'\nimport { CSSToCitricAdapter } from '@stack-spot/portal-theme'\nimport '@stack-spot/portal-theme/dist/theme.css'\nimport { useLanguage } from '@stack-spot/portal-translate'\nimport { useState } from 'react'\nimport { Login, LoginProps } from './Login'\nimport { SessionManager } from './SessionManager'\n\ntype AuthStatus = 'unknown' | 'authenticated' | 'unauthenticated'\n\ninterface Props {\n children: React.ReactElement,\n onLogin?: () => void,\n onSession?: () => void,\n onChangeStatus?: (status: AuthStatus) => void,\n customLoginProps?: Omit<LoginProps, 'onSubmit' | 'initialValue'>,\n sessionManager?: SessionManager,\n}\n\nexport const Authenticated = ({ children, onLogin, onSession, customLoginProps, sessionManager, onChangeStatus }: Props) => {\n const [authStatus, setAuthStatus] = useState<AuthStatus>('unknown')\n const language = useLanguage()\n sessionManager ??= SessionManager.instance\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n\n useEffectOnce(() => {\n async function checkAuth() {\n if (!sessionManager) throw new Error('Please, provide a sessionManager')\n await sessionManager.restoreSession()\n if (sessionManager.urlHasThirdPartyLoginData()) {\n await sessionManager.completeThirdPartyLogin()\n onLogin?.()\n }\n if (sessionManager.hasSession()) {\n setAuthStatus('authenticated')\n onSession?.()\n onChangeStatus?.('authenticated')\n } else {\n setAuthStatus('unauthenticated')\n onChangeStatus?.('unauthenticated')\n }\n }\n\n checkAuth()\n })\n\n if (authStatus === 'unknown') return null\n if (authStatus === 'authenticated') return children\n\n return (\n <CSSToCitricAdapter>\n <Flex justifyContent=\"center\" alignItems=\"center\" flex={1} style={{ height: '100%' }}>\n <Login\n style={{ width: '360px' }}\n onSubmit={data => sessionManager.startThirdPartyLogin({ ...data, locale: language })}\n initialValue={sessionManager.getEmailForLogin()}\n {...(customLoginProps || {})}\n />\n </Flex>\n </CSSToCitricAdapter>\n )\n}\n","import { Session } from '@stack-spot/auth'\nimport { useEffect, useState } from 'react'\nimport { SessionManager } from './SessionManager'\n\nexport function useSession() {\n const manager = SessionManager.instance\n const [session, setSession] = useState<Session | undefined>(manager?.hasSession() ? manager.getSession() : undefined)\n useEffect(() => {\n return manager?.onChange(setSession)\n }, [])\n return session\n}\n"],"names":["error","sessionKey","__spreadProps","__spreadValues"],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@stack-spot/auth-react",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "main": "out/index.js",
5
5
  "module": "out/index.mjs",
6
6
  "typings": "out/index.d.ts",
7
+ "scripts": {
8
+ "compile": "rimraf out && rollup -c",
9
+ "build": "pnpm compile"
10
+ },
7
11
  "devDependencies": {
8
12
  "@typescript-eslint/eslint-plugin": "^6.21.0",
9
13
  "@typescript-eslint/parser": "^6.21.0",
@@ -27,14 +31,10 @@
27
31
  "@citric/ui": "^5.0.0 || ^6.0.0",
28
32
  "@stack-spot/auth": "^5.0.0",
29
33
  "@stack-spot/portal-theme": "^1.0.0",
30
- "@stack-spot/portal-components": "^1.0.0",
34
+ "@stack-spot/portal-components": "^1.0.0 || ^2.0.0",
31
35
  "@stack-spot/portal-translate": "^1.0.0",
32
36
  "react": "^18.2.0",
33
37
  "react-dom": "^18.2.0",
34
38
  "styled-components": "^6.1.10"
35
- },
36
- "scripts": {
37
- "compile": "rimraf out && rollup -c",
38
- "build": "pnpm compile"
39
39
  }
40
- }
40
+ }
package/src/Login.tsx CHANGED
@@ -57,7 +57,7 @@ const LoginBox = styled.form`
57
57
 
58
58
  .separator {
59
59
  padding: 0 8px;
60
- background-color: ${theme.color.light['400']};
60
+ background-color: ${theme.color.light['300']};
61
61
  color: ${theme.color.light['700']};
62
62
  display: flex;
63
63
  flex-direction: row;
@@ -4,9 +4,24 @@ import { redirect } from './utils/redirect'
4
4
 
5
5
  const sessionKey = 'session'
6
6
 
7
- interface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant' | 'redirectUrl'> {
8
- loginUrl: string,
7
+ interface SessionManagerConfig extends Pick<AuthConfig, 'accountUrl' | 'authUrl' | 'clientId' | 'defaultTenant'> {
8
+ /**
9
+ * The URL to redirect to when the user logs out.
10
+ * @default location.origin
11
+ */
12
+ loginUrl?: string,
13
+ /**
14
+ * The URL to redirect to when the login completes in the authentication app. If not provided, will be the same as `loginUrl`.
15
+ * @default loginUrl
16
+ */
17
+ redirectUrl?: string,
18
+ /**
19
+ * Forbidden authentication types to this Session Manager.
20
+ */
9
21
  blockedAuthTypes?: ThirdPartyAuthType[]
22
+ /**
23
+ * A URL to send login events to (observability).
24
+ */
10
25
  rdUrl?: string,
11
26
  }
12
27
 
@@ -29,9 +44,12 @@ export class SessionManager {
29
44
  static instance: SessionManager | undefined
30
45
 
31
46
  private constructor(config: SessionManagerConfig) {
47
+ config.loginUrl ||= location.origin
48
+ const redirectUrl = (config.redirectUrl || config.loginUrl).replace(/([^/])$/, '$1/') // the trailing "/" is required by Stackspot IAM.
32
49
  this.config = config
33
50
  this.auth = new AuthManager<AuthExtraData>({
34
51
  ...config,
52
+ redirectUrl,
35
53
  storage: localStorage,
36
54
  sessionPersistence: {
37
55
  load: () => localStorage.getItem(sessionKey),
@@ -99,7 +117,7 @@ export class SessionManager {
99
117
  this.current = undefined
100
118
  localStorage.removeItem(sessionKey)
101
119
  sessionCookie.delete()
102
- if (redirectToLogin) await redirect(this.config.loginUrl)
120
+ if (redirectToLogin && this.config.loginUrl) await redirect(this.config.loginUrl)
103
121
  }
104
122
 
105
123
  async logout() {