@pofsis-nbt/pofsis-auth 2.0.0 → 2.1.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.
Files changed (45) hide show
  1. package/Documentation.md +151 -143
  2. package/README.md +143 -130
  3. package/dist/PofsisAuth.d.ts +1 -1
  4. package/dist/PofsisAuth.d.ts.map +1 -1
  5. package/dist/{PofsisAuthClient-CEw_lL5S.js → PofsisAuthClient-Duybofpq.js} +162 -46
  6. package/dist/PofsisAuthClient-Duybofpq.js.map +1 -0
  7. package/dist/PofsisAuthClient-c4lzLzjV.cjs +2 -0
  8. package/dist/PofsisAuthClient-c4lzLzjV.cjs.map +1 -0
  9. package/dist/{RequireAuth-CPhXupYh.cjs → RequireAuth-BkYhk-9p.cjs} +2 -2
  10. package/dist/{RequireAuth-CPhXupYh.cjs.map → RequireAuth-BkYhk-9p.cjs.map} +1 -1
  11. package/dist/{RequireAuth-DFa8_MR1.js → RequireAuth-DroX56rd.js} +67 -62
  12. package/dist/{RequireAuth-DFa8_MR1.js.map → RequireAuth-DroX56rd.js.map} +1 -1
  13. package/dist/auth/authLaunch.d.ts.map +1 -1
  14. package/dist/auth/config.d.ts.map +1 -1
  15. package/dist/core/PofsisAuthClient.d.ts +2 -0
  16. package/dist/core/PofsisAuthClient.d.ts.map +1 -1
  17. package/dist/core/index.d.ts +2 -2
  18. package/dist/core/index.d.ts.map +1 -1
  19. package/dist/core/popupProtocol.d.ts +11 -1
  20. package/dist/core/popupProtocol.d.ts.map +1 -1
  21. package/dist/core.cjs +1 -1
  22. package/dist/core.js +2 -2
  23. package/dist/elements/index.d.ts.map +1 -1
  24. package/dist/elements.cjs +1 -1
  25. package/dist/elements.cjs.map +1 -1
  26. package/dist/elements.js +8 -3
  27. package/dist/elements.js.map +1 -1
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -3
  32. package/dist/pofsis-auth-elements.js +1 -1
  33. package/dist/pofsis-auth-elements.js.map +1 -1
  34. package/dist/react/index.d.ts +1 -1
  35. package/dist/react/index.d.ts.map +1 -1
  36. package/dist/react.cjs +1 -1
  37. package/dist/react.js +1 -1
  38. package/dist/types.d.ts +13 -2
  39. package/dist/types.d.ts.map +1 -1
  40. package/docs/application-id-consumer-migration.md +180 -0
  41. package/docs/popup-integration.md +188 -162
  42. package/package.json +87 -87
  43. package/dist/PofsisAuthClient-B3YHqgZL.cjs +0 -2
  44. package/dist/PofsisAuthClient-B3YHqgZL.cjs.map +0 -1
  45. package/dist/PofsisAuthClient-CEw_lL5S.js.map +0 -1
@@ -0,0 +1,180 @@
1
+ # Application-ID Integration Update
2
+
3
+ This guide covers only the frontend integration changes required to migrate an existing POFSIS tool
4
+ from the legacy `@pofsis/auth-react` package and application-name configuration to
5
+ `@pofsis-nbt/pofsis-auth` v2 and an immutable application UUID.
6
+
7
+ ## Required values
8
+
9
+ Obtain the correct `applications.id` UUID for each environment from the Auth application registry.
10
+ Do not reuse a development UUID in staging or production unless that environment has been verified
11
+ to use the same registration.
12
+
13
+ For Vite applications, configure:
14
+
15
+ ```env
16
+ VITE_POFSIS_APPLICATION_ID=<APPLICATION_UUID>
17
+ VITE_POFSIS_API_BASE_URL=https://dev-auth.pofsis.com/api
18
+ VITE_POFSIS_AUTH_URL=https://dev-auth.pofsis.com/authorize
19
+ VITE_POFSIS_SCOPE=openid profile email
20
+ ```
21
+
22
+ Remove:
23
+
24
+ ```env
25
+ VITE_POFSIS_APP_NAME=<LEGACY_APPLICATION_NAME>
26
+ ```
27
+
28
+ The application UUID is a public identifier, not a secret. Do not add `client_id`, redirect URI, or
29
+ logout URI to the frontend environment. The library discovers those values through Auth BE using
30
+ the UUID and the browser's exact origin.
31
+
32
+ ## Upgrade the package
33
+
34
+ Remove the old dependency:
35
+
36
+ ```powershell
37
+ npm uninstall @pofsis/auth-react
38
+ ```
39
+
40
+ Install v2:
41
+
42
+ ```powershell
43
+ npm install @pofsis-nbt/pofsis-auth@^2.0.0
44
+ ```
45
+
46
+ If the old package was vendored under `packages/pofsis-auth-react`, delete that directory after all
47
+ imports have been replaced. Remove any Vite `optimizeDeps.exclude` entry that existed only for the
48
+ vendored package.
49
+
50
+ Replace imports throughout the tool:
51
+
52
+ ```diff
53
+ - import { PofsisAuth, RequireAuth, useAuth } from '@pofsis/auth-react'
54
+ + import { PofsisAuth, RequireAuth, useAuth } from '@pofsis-nbt/pofsis-auth'
55
+ ```
56
+
57
+ Import the v2 stylesheet exactly once in the application entry point:
58
+
59
+ ```js
60
+ import '@pofsis-nbt/pofsis-auth/style.css'
61
+ ```
62
+
63
+ Check for remaining legacy references:
64
+
65
+ ```powershell
66
+ rg "@pofsis/auth-react|VITE_POFSIS_APP_NAME|appName|\?app=" src .envs package.json vite.config.*
67
+ ```
68
+
69
+ ## Configure the React provider
70
+
71
+ The library does not read environment variables directly. The consuming application must pass its
72
+ configuration to `PofsisAuth`:
73
+
74
+ ```jsx
75
+ import { PofsisAuth } from '@pofsis-nbt/pofsis-auth'
76
+
77
+ <PofsisAuth
78
+ applicationId={import.meta.env.VITE_POFSIS_APPLICATION_ID}
79
+ apiBaseUrl={import.meta.env.VITE_POFSIS_API_BASE_URL}
80
+ authUrl={import.meta.env.VITE_POFSIS_AUTH_URL}
81
+ scope={import.meta.env.VITE_POFSIS_SCOPE}
82
+ callbackPath="/auth/callback"
83
+ postLoginPath="/"
84
+ >
85
+ <App />
86
+ </PofsisAuth>
87
+ ```
88
+
89
+ `applicationId`, `apiBaseUrl`, and `authUrl` are required. Missing values fail during configuration
90
+ instead of silently selecting another application.
91
+
92
+ ## Update protected routes
93
+
94
+ The v2 `RequireAuth` contract is:
95
+
96
+ ```text
97
+ RequireAuth({ children, fallback?, onUnauthenticated? })
98
+ ```
99
+
100
+ Legacy `mode` and `returnTo` props are not supported. The basic integration is:
101
+
102
+ ```jsx
103
+ import { RequireAuth } from '@pofsis-nbt/pofsis-auth'
104
+
105
+ function ProtectedRoute({ children }) {
106
+ return (
107
+ <RequireAuth fallback={<LoadingScreen />}>
108
+ {children}
109
+ </RequireAuth>
110
+ )
111
+ }
112
+ ```
113
+
114
+ Without `onUnauthenticated`, `RequireAuth` starts its default redirect login. A tool that requires
115
+ different unauthenticated behavior can provide its own `onUnauthenticated` callback based on that
116
+ tool's product flow; this guide does not prescribe login, signup, popup, or return-path behavior.
117
+
118
+ ## Keep protected API calls connected
119
+
120
+ The Axios interceptor signature is unchanged:
121
+
122
+ ```js
123
+ import { attachAuthInterceptor } from '@pofsis-nbt/pofsis-auth'
124
+
125
+ attachAuthInterceptor(apiClient, auth.getAccessToken, auth.refreshSession)
126
+ ```
127
+
128
+ Attach it only once per Axios client. If it is attached from a component, retain and call the
129
+ returned cleanup function when that component unmounts.
130
+
131
+ ## Framework-neutral integration
132
+
133
+ Non-React applications can use the core client:
134
+
135
+ ```js
136
+ import { createPofsisAuth } from '@pofsis-nbt/pofsis-auth/core'
137
+
138
+ const auth = createPofsisAuth({
139
+ applicationId: runtimeConfig.applicationId,
140
+ apiBaseUrl: runtimeConfig.apiBaseUrl,
141
+ authUrl: runtimeConfig.authUrl,
142
+ scope: 'openid profile email',
143
+ callbackPath: '/auth/callback',
144
+ })
145
+ ```
146
+
147
+ ## Consumer validation
148
+
149
+ Run the tool's standard checks:
150
+
151
+ ```powershell
152
+ npm install
153
+ npm run test
154
+ npm run lint
155
+ npm run format:check
156
+ npm run build
157
+ ```
158
+
159
+ Run browser or E2E tests when available. Confirm that:
160
+
161
+ - Client discovery uses the configured application UUID and current browser origin.
162
+ - The generated authorization URL contains `client_id`, `state`, and PKCE fields.
163
+ - The authorization URL does not contain `app`, an application name/code, or `application_id`.
164
+ - The tool's existing authentication entry behavior remains correct for its product flow.
165
+ - `/auth/callback` returns to the requested safe local route.
166
+ - Refresh, logout, profile editing, and protected API calls still work.
167
+ - Invalid UUIDs and origins show an application error and do not start authentication.
168
+
169
+ ## Per-environment integration checklist
170
+
171
+ - [ ] Confirm the environment-specific application UUID with the Auth owner.
172
+ - [ ] Replace the old package and all imports.
173
+ - [ ] Remove the vendored package and Vite exclusion.
174
+ - [ ] Replace `VITE_POFSIS_APP_NAME` with `VITE_POFSIS_APPLICATION_ID`.
175
+ - [ ] Pass explicit provider configuration.
176
+ - [ ] Update protected routes that used legacy `mode` or `returnTo` props.
177
+ - [ ] Import the package stylesheet once.
178
+ - [ ] Run unit, lint, formatting, build, and E2E checks.
179
+ - [ ] Smoke-test login, signup, callback, refresh, logout, and protected API calls.
180
+ - [ ] Repeat separately for development, staging, and production.
@@ -1,162 +1,188 @@
1
- # POFSIS Auth popup integration
2
-
3
- `@pofsis-nbt/pofsis-auth` opens the hosted POFSIS Auth UI in a popup and completes OAuth 2.0 Authorization Code with PKCE in the calling tool. Passwords, OTPs, passkeys, refresh tokens, and Cognito credentials remain owned by POFSIS Auth.
4
-
5
- ## Prerequisites
6
-
7
- - Register the tool's exact origin, callback URI, and logout URI with POFSIS Auth for each environment.
8
- - Use HTTPS outside local development and allow the tool origin in Auth CORS configuration.
9
- - Obtain the immutable registered application UUID and allowed public scopes.
10
- - Never put an OAuth client secret or organization service credential in a browser application.
11
-
12
- ## Package entry points
13
-
14
- ```bash
15
- npm install @pofsis-nbt/pofsis-auth
16
- ```
17
-
18
- | Import | Use |
19
- | ---------------------------------- | ----------------------------------------------- |
20
- | `@pofsis-nbt/pofsis-auth/core` | Framework-neutral browser SDK |
21
- | `@pofsis-nbt/pofsis-auth/react` | React provider, hooks, guards, and API helper |
22
- | `@pofsis-nbt/pofsis-auth/elements` | Optional `<pofsis-sign-in>` Web Component |
23
- | `@pofsis-nbt/pofsis-auth` | Backward-compatible React API plus core exports |
24
-
25
- ## Framework-neutral setup
26
-
27
- ```js
28
- import { createPofsisAuth, relayPopupCallback } from '@pofsis-nbt/pofsis-auth/core'
29
-
30
- const auth = createPofsisAuth({
31
- applicationId: '11111111-1111-4111-8111-111111111111',
32
- apiBaseUrl: 'https://auth-api.example.com',
33
- authUrl: 'https://auth.example.com/authorize',
34
- })
35
-
36
- // Run this before rendering the normal app on /auth/callback.
37
- if (location.pathname === '/auth/callback') {
38
- const relayed = relayPopupCallback()
39
- if (!relayed) {
40
- const params = new URLSearchParams(location.search)
41
- await auth.completeRedirectCallback(params.get('code'), params.get('state'))
42
- }
43
- }
44
- ```
45
-
46
- Call popup authentication directly from a click or other user gesture:
47
-
48
- ```js
49
- document.querySelector('#login').addEventListener('click', async () => {
50
- const result = await auth.login({
51
- presentation: 'popup',
52
- screen: 'login',
53
- returnUrl: location.pathname + location.search,
54
- })
55
- if (result.status === 'authenticated') renderUser(result.user)
56
- })
57
- ```
58
-
59
- The SDK calls `window.open()` itself. A blocked popup falls back to a full-page redirect. Route guards should explicitly use `presentation: 'redirect'` because they may not run during a user gesture.
60
-
61
- ## Initialization parameters
62
-
63
- | Parameter | Required | Default | Meaning |
64
- | ----------------- | -------: | ---------------------- | ---------------------------------- |
65
- | `applicationId` | yes | - | Immutable `applications.id` UUID |
66
- | `apiBaseUrl` | yes | - | Public POFSIS Auth API base URL |
67
- | `authUrl` | yes | - | Hosted Auth `/authorize` URL |
68
- | `scope` | no | `openid profile email` | Registered OAuth scopes |
69
- | `callbackPath` | no | `/auth/callback` | Local tool callback route |
70
- | `popup.width` | no | `480` | Popup width in pixels |
71
- | `popup.height` | no | `720` | Popup height in pixels |
72
- | `popup.name` | no | `pofsis-auth` | Reused browser window name |
73
- | `popup.timeoutMs` | no | `300000` | Authentication timeout |
74
-
75
- ## Launch parameters
76
-
77
- | Parameter | Required | Default | Meaning |
78
- | -------------- | -------: | ------------ | ---------------------------------------------------- |
79
- | `presentation` | no | `popup` | `popup` or full-page `redirect` |
80
- | `screen` | no | `login` | `login`, `signup`, or `reset` |
81
- | `method` | no | Auth default | `password`, `passkey`, or `otp` |
82
- | `loginHint` | no | - | Editable email or Philippine mobile hint |
83
- | `returnUrl` | no | - | Safe application-relative route restored after login |
84
-
85
- `returnUrl` must start with one `/` and must not start with `//`. Do not put invitation secrets or external URLs in it.
86
-
87
- Convenience methods use the same protocol:
88
-
89
- ```js
90
- await auth.signup({ loginHint: 'employee@example.com', method: 'otp' })
91
- await auth.resetPassword({ loginHint: 'employee@example.com' })
92
- await auth.login({ method: 'password' })
93
- await auth.login({ method: 'passkey' })
94
- ```
95
-
96
- ## React
97
-
98
- ```tsx
99
- import { PofsisAuth, useAuth } from '@pofsis-nbt/pofsis-auth/react'
100
- import '@pofsis-nbt/pofsis-auth/style.css'
101
-
102
- function SignInButton() {
103
- const { login } = useAuth()
104
- return <button onClick={() => void login({ presentation: 'popup' })}>Sign in</button>
105
- }
106
-
107
- export function App() {
108
- return (
109
- <PofsisAuth
110
- applicationId="11111111-1111-4111-8111-111111111111"
111
- apiBaseUrl="https://auth-api.example.com"
112
- authUrl="https://auth.example.com/authorize"
113
- >
114
- <SignInButton />
115
- </PofsisAuth>
116
- )
117
- }
118
- ```
119
-
120
- `RequireAuth` deliberately uses redirect presentation. The provider handles popup and full-page callbacks at `callbackPath`.
121
-
122
- ## Web Component
123
-
124
- Import the package entry or host the generated standalone `dist/pofsis-auth-elements.js` bundle:
125
-
126
- ```html
127
- <script type="module" src="https://auth.pofsis.com/sdk/pofsis-auth-elements.js"></script>
128
-
129
- <pofsis-sign-in
130
- application-id="11111111-1111-4111-8111-111111111111"
131
- api-base-url="https://auth-api.example.com"
132
- auth-url="https://auth.example.com/authorize"
133
- return-url="/dashboard"
134
- >Sign in</pofsis-sign-in
135
- >
136
- ```
137
-
138
- The element dispatches `pofsis-auth-authenticated`, `pofsis-auth-cancelled`, `pofsis-auth-redirecting`, and `pofsis-auth-error`. It is only a launch control; credential fields always render on the hosted Auth origin.
139
-
140
- ## Session and API calls
141
-
142
- ```js
143
- const unsubscribe = auth.subscribe((session) => updateHeader(session?.user))
144
- const token = auth.getAccessToken()
145
- await auth.refreshSession()
146
- await auth.logout()
147
- unsubscribe()
148
- ```
149
-
150
- Access tokens are held in memory. Use `getAccessToken()` to add a bearer token to the tool's own API calls. Do not write access tokens to URLs or browser storage.
151
-
152
- ## Results and failures
153
-
154
- - `authenticated`: code exchange succeeded and includes the user.
155
- - `cancelled`: the user closed the popup; this is not an authentication error.
156
- - `redirecting`: the SDK started full-page navigation, including popup-blocked fallback.
157
- - Invalid state, origin, popup source, or correlation messages are ignored or rejected.
158
- - A timeout rejects the launch and closes the popup.
159
-
160
- For callback URI mismatches, verify the exact deployed origin and registered URI. For CORS or silent-session failures, verify Auth's origin registry and credentialed cookie configuration. A cancelled or unavailable passkey remains an Auth-screen concern and must retain the password fallback.
161
-
162
- The frontend SDK must never call `/api/internal`, Cognito administration APIs, or organization provisioning APIs. Those flows remain tool-backend to Auth-backend operations.
1
+ # POFSIS Auth popup and modal integration
2
+
3
+ `@pofsis-nbt/pofsis-auth` opens the hosted POFSIS Auth UI in a popup, an SDK-owned iframe modal, or a full-page redirect and completes OAuth 2.0 Authorization Code with PKCE in the calling tool. Passwords, OTPs, passkeys, refresh tokens, and Cognito credentials remain owned by POFSIS Auth.
4
+
5
+ ## Prerequisites
6
+
7
+ - Register the tool's exact origin, callback URI, and logout URI with POFSIS Auth for each environment.
8
+ - Use HTTPS outside local development and allow the tool origin in Auth CORS configuration.
9
+ - Obtain the immutable registered application UUID and allowed public scopes.
10
+ - Never put an OAuth client secret or organization service credential in a browser application.
11
+
12
+ ## Package entry points
13
+
14
+ ```bash
15
+ npm install @pofsis-nbt/pofsis-auth
16
+ ```
17
+
18
+ | Import | Use |
19
+ | ---------------------------------- | ----------------------------------------------- |
20
+ | `@pofsis-nbt/pofsis-auth/core` | Framework-neutral browser SDK |
21
+ | `@pofsis-nbt/pofsis-auth/react` | React provider, hooks, guards, and API helper |
22
+ | `@pofsis-nbt/pofsis-auth/elements` | Optional `<pofsis-sign-in>` Web Component |
23
+ | `@pofsis-nbt/pofsis-auth` | Backward-compatible React API plus core exports |
24
+
25
+ ## Framework-neutral setup
26
+
27
+ ```js
28
+ import { createPofsisAuth, relayAuthCallback } from '@pofsis-nbt/pofsis-auth/core'
29
+
30
+ const auth = createPofsisAuth({
31
+ applicationId: '11111111-1111-4111-8111-111111111111',
32
+ apiBaseUrl: 'https://auth-api.example.com',
33
+ authUrl: 'https://auth.example.com/authorize',
34
+ })
35
+
36
+ // Run this before rendering the normal app on /auth/callback.
37
+ if (location.pathname === '/auth/callback') {
38
+ const relayed = relayAuthCallback()
39
+ if (!relayed) {
40
+ const params = new URLSearchParams(location.search)
41
+ await auth.completeRedirectCallback(params.get('code'), params.get('state'))
42
+ }
43
+ }
44
+ ```
45
+
46
+ Call popup authentication directly from a click or other user gesture:
47
+
48
+ ```js
49
+ document.querySelector('#login').addEventListener('click', async () => {
50
+ const result = await auth.login({
51
+ presentation: 'popup',
52
+ screen: 'login',
53
+ returnUrl: location.pathname + location.search,
54
+ })
55
+ if (result.status === 'authenticated') renderUser(result.user)
56
+ })
57
+ ```
58
+
59
+ The SDK calls `window.open()` itself. A blocked popup falls back to a full-page redirect. Route guards should explicitly use `presentation: 'redirect'` because they may not run during a user gesture.
60
+
61
+ To keep Auth visually inside the tool, request the modal presentation:
62
+
63
+ ```js
64
+ const result = await auth.login({
65
+ presentation: 'modal',
66
+ screen: 'login',
67
+ returnUrl: location.pathname + location.search,
68
+ })
69
+ ```
70
+
71
+ The SDK creates an accessible modal and embeds the hosted Auth origin in an iframe. The tool cannot inspect credential fields. Close, Escape, and backdrop dismissal resolve with `status: 'cancelled'`. A modal does not silently fall back to popup or redirect if embedding fails.
72
+
73
+ ## Initialization parameters
74
+
75
+ | Parameter | Required | Default | Meaning |
76
+ | ---------------------- | -------: | ---------------------- | -------------------------------- |
77
+ | `applicationId` | yes | - | Immutable `applications.id` UUID |
78
+ | `apiBaseUrl` | yes | - | Public POFSIS Auth API base URL |
79
+ | `authUrl` | yes | - | Hosted Auth `/authorize` URL |
80
+ | `scope` | no | `openid profile email` | Registered OAuth scopes |
81
+ | `callbackPath` | no | `/auth/callback` | Local tool callback route |
82
+ | `popup.width` | no | `480` | Popup width in pixels |
83
+ | `popup.height` | no | `720` | Popup height in pixels |
84
+ | `popup.name` | no | `pofsis-auth` | Reused browser window name |
85
+ | `popup.timeoutMs` | no | `300000` | Authentication timeout |
86
+ | `modal.width` | no | `480` | Modal width in pixels |
87
+ | `modal.height` | no | `720` | Modal height in pixels |
88
+ | `modal.timeoutMs` | no | `300000` | Authentication timeout |
89
+ | `modal.readyTimeoutMs` | no | `15000` | Secure iframe handshake timeout |
90
+
91
+ ## Launch parameters
92
+
93
+ | Parameter | Required | Default | Meaning |
94
+ | -------------- | -------: | ------------ | ---------------------------------------------------- |
95
+ | `presentation` | no | `popup` | `popup`, iframe `modal`, or full-page `redirect` |
96
+ | `screen` | no | `login` | `login`, `signup`, or `reset` |
97
+ | `method` | no | Auth default | `password`, `passkey`, or `otp` |
98
+ | `loginHint` | no | - | Editable email or Philippine mobile hint |
99
+ | `returnUrl` | no | - | Safe application-relative route restored after login |
100
+
101
+ `returnUrl` must start with one `/` and must not start with `//`. Do not put invitation secrets or external URLs in it.
102
+
103
+ Convenience methods use the same protocol:
104
+
105
+ ```js
106
+ await auth.signup({ loginHint: 'employee@example.com', method: 'otp' })
107
+ await auth.resetPassword({ loginHint: 'employee@example.com' })
108
+ await auth.login({ method: 'password' })
109
+ await auth.login({ method: 'passkey' })
110
+ ```
111
+
112
+ ## React
113
+
114
+ ```tsx
115
+ import { PofsisAuth, useAuth } from '@pofsis-nbt/pofsis-auth/react'
116
+ import '@pofsis-nbt/pofsis-auth/style.css'
117
+
118
+ function SignInButton() {
119
+ const { login } = useAuth()
120
+ return <button onClick={() => void login({ presentation: 'modal' })}>Sign in</button>
121
+ }
122
+
123
+ export function App() {
124
+ return (
125
+ <PofsisAuth
126
+ applicationId="11111111-1111-4111-8111-111111111111"
127
+ apiBaseUrl="https://auth-api.example.com"
128
+ authUrl="https://auth.example.com/authorize"
129
+ modal={{ width: 480, height: 720 }}
130
+ >
131
+ <SignInButton />
132
+ </PofsisAuth>
133
+ )
134
+ }
135
+ ```
136
+
137
+ `RequireAuth` deliberately uses redirect presentation. The provider handles popup, modal, and full-page callbacks at `callbackPath`.
138
+
139
+ ## Web Component
140
+
141
+ Import the package entry or host the generated standalone `dist/pofsis-auth-elements.js` bundle:
142
+
143
+ ```html
144
+ <script type="module" src="https://auth.pofsis.com/sdk/pofsis-auth-elements.js"></script>
145
+
146
+ <pofsis-sign-in
147
+ application-id="11111111-1111-4111-8111-111111111111"
148
+ api-base-url="https://auth-api.example.com"
149
+ auth-url="https://auth.example.com/authorize"
150
+ return-url="/dashboard"
151
+ presentation="modal"
152
+ >Sign in</pofsis-sign-in
153
+ >
154
+ ```
155
+
156
+ The element dispatches `pofsis-auth-authenticated`, `pofsis-auth-cancelled`, `pofsis-auth-redirecting`, and `pofsis-auth-error`. It is only a launch control; credential fields always render on the hosted Auth origin.
157
+
158
+ ## Iframe security and hosting
159
+
160
+ - The Auth frontend verifies a parent-frame handshake against the registered OAuth client before rendering credentials.
161
+ - The callback accepts messages only from the exact iframe window, expected origin, state, and correlation ID.
162
+ - The iframe is sandboxed and receives only the capabilities needed for forms, scripts, external legal links, and WebAuthn.
163
+ - Auth HTML must not send `X-Frame-Options: DENY` or `SAMEORIGIN`. A CSP `frame-ancestors` directive must include every registered tool origin.
164
+ - Third-party-cookie or WebAuthn restrictions vary by browser. Keep popup or redirect available as an explicit consumer fallback when required by browser policy.
165
+
166
+ ## Session and API calls
167
+
168
+ ```js
169
+ const unsubscribe = auth.subscribe((session) => updateHeader(session?.user))
170
+ const token = auth.getAccessToken()
171
+ await auth.refreshSession()
172
+ await auth.logout()
173
+ unsubscribe()
174
+ ```
175
+
176
+ Access tokens are held in memory. Use `getAccessToken()` to add a bearer token to the tool's own API calls. Do not write access tokens to URLs or browser storage.
177
+
178
+ ## Results and failures
179
+
180
+ - `authenticated`: code exchange succeeded and includes the user.
181
+ - `cancelled`: the user dismissed the popup or modal; this is not an authentication error.
182
+ - `redirecting`: the SDK started full-page navigation, including popup-blocked fallback.
183
+ - Invalid state, origin, popup or iframe source, or correlation messages are ignored or rejected.
184
+ - A timeout rejects the launch and closes the popup or modal. Failure to validate the iframe parent rejects with an embedding error.
185
+
186
+ For callback URI mismatches, verify the exact deployed origin and registered URI. For CORS or silent-session failures, verify Auth's origin registry and credentialed cookie configuration. A cancelled or unavailable passkey remains an Auth-screen concern and must retain the password fallback.
187
+
188
+ The frontend SDK must never call `/api/internal`, Cognito administration APIs, or organization provisioning APIs. Those flows remain tool-backend to Auth-backend operations.