central-auth-js-sdk 1.0.10
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/INTEGRATION_GUIDE.md +473 -0
- package/README.md +386 -0
- package/auth.js +159 -0
- package/core/api.js +226 -0
- package/core/env-config.js +25 -0
- package/core/events.js +28 -0
- package/core/flow.js +131 -0
- package/core/login-config.js +73 -0
- package/core/login-flow.js +148 -0
- package/core/login-state.js +50 -0
- package/core/progress-storage.js +17 -0
- package/core/state.js +55 -0
- package/index.js +20 -0
- package/login.js +318 -0
- package/package.json +35 -0
- package/signup.js +315 -0
- package/styles.css +947 -0
- package/theme.js +277 -0
- package/ui/components.js +94 -0
- package/ui/layout.js +100 -0
- package/ui/screens/email-entry.js +136 -0
- package/ui/screens/email-verify.js +96 -0
- package/ui/screens/face-registration.js +125 -0
- package/ui/screens/index.js +67 -0
- package/ui/screens/login/entry.js +63 -0
- package/ui/screens/login/frs.js +134 -0
- package/ui/screens/login/identifier-email.js +57 -0
- package/ui/screens/login/identifier-mobile.js +85 -0
- package/ui/screens/login/index.js +103 -0
- package/ui/screens/login/otp.js +79 -0
- package/ui/screens/login/password.js +65 -0
- package/ui/screens/login/success.js +32 -0
- package/ui/screens/mobile-entry.js +79 -0
- package/ui/screens/mobile-verify.js +79 -0
- package/ui/screens/password-setup.js +137 -0
- package/ui/screens/success.js +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# Central Auth Welcome Flow SDK
|
|
2
|
+
|
|
3
|
+
Vanilla JavaScript signup and login flows — embeddable into any web application. No React, Angular, or Vue.
|
|
4
|
+
|
|
5
|
+
**Integrators:** See **[INTEGRATION_GUIDE.md](INTEGRATION_GUIDE.md)** for how to pull the SDK and use all functionalities (install, config, signup/login, callbacks, tokens, and a full example).
|
|
6
|
+
|
|
7
|
+
## Distributing the SDK
|
|
8
|
+
|
|
9
|
+
**Simplest options:**
|
|
10
|
+
|
|
11
|
+
### 1. **npm (recommended)**
|
|
12
|
+
|
|
13
|
+
Publish the `sdk` folder as its own package so integrators can install it with one command.
|
|
14
|
+
|
|
15
|
+
- Log in to npm (one-time): `npm login` (you need an account at [npmjs.com](https://www.npmjs.com/signup)).
|
|
16
|
+
- From the repo root, go to the SDK folder and publish:
|
|
17
|
+
```bash
|
|
18
|
+
cd sdk
|
|
19
|
+
npm publish
|
|
20
|
+
```
|
|
21
|
+
Use `npm publish --access public` if the package name is scoped (e.g. `@your-org/central-auth-sdk`).
|
|
22
|
+
|
|
23
|
+
- Integrators then:
|
|
24
|
+
```bash
|
|
25
|
+
npm install central-auth-sdk
|
|
26
|
+
```
|
|
27
|
+
```javascript
|
|
28
|
+
import { startSignup, startLogin } from 'central-auth-sdk';
|
|
29
|
+
```
|
|
30
|
+
They also need to load the CSS (e.g. in their app entry or HTML):
|
|
31
|
+
```javascript
|
|
32
|
+
import 'central-auth-sdk/styles.css';
|
|
33
|
+
```
|
|
34
|
+
or
|
|
35
|
+
```html
|
|
36
|
+
<link rel="stylesheet" href="./node_modules/central-auth-sdk/styles.css" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Pros:** Versioning, semver, one install command, works with any bundler.
|
|
40
|
+
**Cons:** Integrators need Node/npm (or equivalent).
|
|
41
|
+
|
|
42
|
+
### 2. **Copy / embed (no build)**
|
|
43
|
+
|
|
44
|
+
Ship the SDK as source in a zip, Git repo, or copy the `sdk` folder into the parent app. The parent app points at the folder (e.g. Vite alias or relative path).
|
|
45
|
+
|
|
46
|
+
- Example (parent app has `sdk/` at repo root):
|
|
47
|
+
```html
|
|
48
|
+
<link rel="stylesheet" href="/sdk/styles.css" />
|
|
49
|
+
<script type="module">
|
|
50
|
+
import { startLogin } from '/sdk/index.js';
|
|
51
|
+
startLogin({ container: '#auth', env: 'dev', loginMethods: { emailPassword: true } });
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Pros:** No publish step, no npm; works with any dev server that serves the `sdk` folder.
|
|
56
|
+
**Cons:** No versioning via registry; updates are manual (replace files or pull from Git).
|
|
57
|
+
|
|
58
|
+
### 3. **CDN / single-file bundle (optional)**
|
|
59
|
+
|
|
60
|
+
For environments without a bundler, you can add a build step that bundles the SDK into a single JS file (and keep `styles.css` separate). Then host it (or publish to npm and use unpkg/jsDelivr). This requires a small Vite/Rollup config that builds `sdk/index.js` into e.g. `dist/central-auth-sdk.js`. Many teams skip this and use option 1 or 2.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Public API (recommended)
|
|
65
|
+
|
|
66
|
+
The SDK exposes **callable functions** so the host application can **initialize and trigger** Sign-Up or Login **programmatically** with **static configuration parameters**.
|
|
67
|
+
|
|
68
|
+
### initializeAuth(config)
|
|
69
|
+
|
|
70
|
+
Call once (e.g. at app load) to set **default configuration**. Optional; you can pass all config when calling `startSignup` / `startLogin` instead.
|
|
71
|
+
|
|
72
|
+
| Parameter | Type | Default | Description |
|
|
73
|
+
|-----------|------|---------|-------------|
|
|
74
|
+
| `env` | string | `'local'` | Environment: `'local'` \| `'dev'` \| `'staging'` \| `'prod'`. SDK uses the predefined API URL for that env. |
|
|
75
|
+
| `appIdentifier` | string | `'control-center'` | App identifier for OAuth and custom login |
|
|
76
|
+
| `defaultContainer` | string \| HTMLElement | — | Default container for rendering (can override in `startSignup` / `startLogin`) |
|
|
77
|
+
| `loginMethods` | object | — | Default enabled login methods (see Login config below) |
|
|
78
|
+
| `frsAsSecondFactor` | boolean | `false` | Default: require face verification after primary auth |
|
|
79
|
+
| `enableFaceRegistration` | boolean | `true` | Whether sign-up flow includes face registration step |
|
|
80
|
+
|
|
81
|
+
**Returns:** `{ startSignup, startLogin, getConfig }`
|
|
82
|
+
|
|
83
|
+
### startSignup(config)
|
|
84
|
+
|
|
85
|
+
Starts the **Sign-Up flow** in the given container. Configuration is **static** (passed when triggering, not collected from the user).
|
|
86
|
+
|
|
87
|
+
| Parameter | Type | Required | Description |
|
|
88
|
+
|-----------|------|----------|-------------|
|
|
89
|
+
| `container` | string \| HTMLElement | yes* | DOM selector or element where the SDK renders (*or set `defaultContainer` in `initializeAuth`) |
|
|
90
|
+
| `env` | string | no | Environment: `'local'` \| `'dev'` \| `'staging'` \| `'prod'` (default from init or `'local'`) |
|
|
91
|
+
| `appIdentifier` | string | no | Override app identifier |
|
|
92
|
+
| `enableFaceRegistration` | boolean | no | Include face registration step (default from init or `true`) |
|
|
93
|
+
|
|
94
|
+
**Returns:** `{ unmount, getState, getFlow, getCurrentStep }` or `null` if container invalid.
|
|
95
|
+
|
|
96
|
+
### startLogin(config)
|
|
97
|
+
|
|
98
|
+
Starts the **Login flow** in the given container with **configurable login methods**.
|
|
99
|
+
|
|
100
|
+
| Parameter | Type | Required | Description |
|
|
101
|
+
|-----------|------|----------|-------------|
|
|
102
|
+
| `container` | string \| HTMLElement | yes* | DOM selector or element where the SDK renders |
|
|
103
|
+
| `env` | string | no | Environment: `'local'` \| `'dev'` \| `'staging'` \| `'prod'` (default from init or `'local'`) |
|
|
104
|
+
| `appIdentifier` | string | no | Override app identifier |
|
|
105
|
+
| `loginMethods` | object | no | Which login methods are enabled (see below) |
|
|
106
|
+
| `frsAsSecondFactor` | boolean | no | Require face verification after primary auth |
|
|
107
|
+
| `onSignUp` | function | no | Callback when user clicks “Sign up” (e.g. switch to signup) |
|
|
108
|
+
|
|
109
|
+
**Enabled login methods** (`loginMethods`):
|
|
110
|
+
|
|
111
|
+
- `emailPassword` — Email + Password
|
|
112
|
+
- `mobilePassword` — Mobile + Password
|
|
113
|
+
- `emailOtp` — Email + OTP
|
|
114
|
+
- `mobileOtp` — Mobile + OTP
|
|
115
|
+
- `social.google` / `social.microsoft` — Social login
|
|
116
|
+
- `emailFrs` — Email + Face (FRS only, no password/OTP)
|
|
117
|
+
|
|
118
|
+
**Returns:** `{ unmount, getState, getFlow, getCurrentStep }` or `null` if container invalid.
|
|
119
|
+
|
|
120
|
+
### Theming (optional)
|
|
121
|
+
|
|
122
|
+
Pass a `theme` object to match the SDK to your app's look. All properties are optional — omit any to keep the SDK default.
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
startSignup({
|
|
126
|
+
container: '#auth-container',
|
|
127
|
+
env: 'dev',
|
|
128
|
+
theme: {
|
|
129
|
+
primaryColor: '#2563EB', // buttons, links, accent
|
|
130
|
+
backgroundColor: '#EFF6FF', // page background
|
|
131
|
+
backgroundImage: 'https://…', // optional full-bleed image
|
|
132
|
+
cardColor: '#FFFFFF', // card panel
|
|
133
|
+
textColor: '#1A1714', // primary text
|
|
134
|
+
fontFamily: '"DM Sans", sans-serif',
|
|
135
|
+
mode: 'auto', // 'light' | 'dark' | 'auto'
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Built-in presets: `import { THEME_PRESETS } from 'central-auth-sdk'` — keys: `default`, `dark`, `ocean`, `forest`, `purple`, `rose`, `midnight`.
|
|
141
|
+
|
|
142
|
+
See [INTEGRATION_GUIDE.md](INTEGRATION_GUIDE.md) § 5.1 for full details.
|
|
143
|
+
|
|
144
|
+
### Example: initialize once, then trigger flows
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
<div id="auth-container"></div>
|
|
148
|
+
<link rel="stylesheet" href="/path/to/sdk/styles.css" />
|
|
149
|
+
<script type="module">
|
|
150
|
+
import { initializeAuth, startSignup, startLogin } from '/path/to/sdk/index.js';
|
|
151
|
+
|
|
152
|
+
const auth = initializeAuth({
|
|
153
|
+
env: 'dev',
|
|
154
|
+
appIdentifier: 'my-app',
|
|
155
|
+
defaultContainer: '#auth-container',
|
|
156
|
+
loginMethods: {
|
|
157
|
+
emailPassword: true,
|
|
158
|
+
emailOtp: true,
|
|
159
|
+
social: { google: true, microsoft: true },
|
|
160
|
+
emailFrs: false,
|
|
161
|
+
},
|
|
162
|
+
frsAsSecondFactor: true,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
let currentInstance = null;
|
|
166
|
+
|
|
167
|
+
function showSignup() {
|
|
168
|
+
if (currentInstance) currentInstance.unmount();
|
|
169
|
+
currentInstance = auth.startSignup({}); // uses defaultContainer + init config
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function showLogin() {
|
|
173
|
+
if (currentInstance) currentInstance.unmount();
|
|
174
|
+
currentInstance = auth.startLogin({
|
|
175
|
+
onSignUp: showSignup,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
showLogin(); // or showSignup()
|
|
180
|
+
</script>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Example: trigger without initializeAuth
|
|
184
|
+
|
|
185
|
+
You can pass **all configuration** when starting a flow (no need to call `initializeAuth`):
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
import { startSignup, startLogin } from '/path/to/sdk/index.js';
|
|
189
|
+
|
|
190
|
+
const signupInstance = startSignup({
|
|
191
|
+
container: '#auth-container',
|
|
192
|
+
env: 'dev',
|
|
193
|
+
appIdentifier: 'my-app',
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const loginInstance = startLogin({
|
|
197
|
+
container: '#auth-container',
|
|
198
|
+
env: 'dev',
|
|
199
|
+
appIdentifier: 'my-app',
|
|
200
|
+
loginMethods: {
|
|
201
|
+
emailPassword: true,
|
|
202
|
+
mobilePassword: true,
|
|
203
|
+
emailOtp: true,
|
|
204
|
+
mobileOtp: true,
|
|
205
|
+
social: { google: true, microsoft: true },
|
|
206
|
+
emailFrs: true,
|
|
207
|
+
},
|
|
208
|
+
frsAsSecondFactor: false,
|
|
209
|
+
onSignUp() {
|
|
210
|
+
loginInstance.unmount();
|
|
211
|
+
startSignup({ container: '#auth-container', env: 'dev' });
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Sending signup result (token + details) back to the parent app
|
|
217
|
+
|
|
218
|
+
When signup **completes** (after the final step, e.g. face registration), the SDK gives the parent app the result in two ways:
|
|
219
|
+
|
|
220
|
+
1. **`onSignupComplete(payload)`** — Pass this callback when starting signup. The SDK calls it **once** when signup finishes, with a single `payload` object that includes:
|
|
221
|
+
- `email`, `mobile`, `userId` (from the flow)
|
|
222
|
+
- Any fields returned by the **final API** call (e.g. `access_token`, `refresh_token`, `user_id`) — the backend can return whatever it needs here.
|
|
223
|
+
|
|
224
|
+
2. **`instance.getState()`** — At any time (including on the success screen), the parent can call `getState()` to read current flow data. After completion, state also includes `signupResult` (the raw final API response).
|
|
225
|
+
|
|
226
|
+
**Example:**
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
const instance = startSignup({
|
|
230
|
+
container: '#auth-container',
|
|
231
|
+
env: 'dev',
|
|
232
|
+
appIdentifier: 'my-app',
|
|
233
|
+
onSignupComplete(payload) {
|
|
234
|
+
// payload.email, payload.mobile, payload.userId
|
|
235
|
+
// payload.access_token, payload.refresh_token (if your API returns them)
|
|
236
|
+
console.log('Signup complete', payload);
|
|
237
|
+
myApp.saveSession(payload.access_token);
|
|
238
|
+
instance.unmount();
|
|
239
|
+
myApp.redirectToDashboard();
|
|
240
|
+
},
|
|
241
|
+
onContinue() {
|
|
242
|
+
// User clicked "Go to Dashboard" / "Back to Home" on the success screen
|
|
243
|
+
instance.unmount();
|
|
244
|
+
myApp.redirectToDashboard();
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The backend should return token (and any other session data) in the **final signup API response** (e.g. `POST /signup/fr/enroll` or the social FR enroll endpoint). The SDK forwards that response into `payload` and into `getState().signupResult`.
|
|
250
|
+
|
|
251
|
+
### Sending login result (token + details) back to the parent app
|
|
252
|
+
|
|
253
|
+
When **login completes** (after the final successful API call — password, OTP, or FRS), the SDK gives the parent app the result in the same way as signup:
|
|
254
|
+
|
|
255
|
+
1. **`onLoginComplete(payload)`** — Pass this callback when starting login. The SDK calls it **once** when login finishes, with a single `payload` object that includes:
|
|
256
|
+
- `identifier` (email or mobile used to sign in)
|
|
257
|
+
- Any fields returned by the **final API** call (e.g. `access_token`, `refresh_token`, `user_id`)
|
|
258
|
+
|
|
259
|
+
2. **`instance.getState()`** — After completion, state includes `loginResult` (the raw final API response).
|
|
260
|
+
|
|
261
|
+
3. **`onContinue()`** — Called when the user clicks **Continue** on the login success screen (e.g. to unmount and redirect).
|
|
262
|
+
|
|
263
|
+
**Example:**
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
const instance = startLogin({
|
|
267
|
+
container: '#auth-container',
|
|
268
|
+
env: 'dev',
|
|
269
|
+
appIdentifier: 'my-app',
|
|
270
|
+
loginMethods: { emailPassword: true },
|
|
271
|
+
onLoginComplete(payload) {
|
|
272
|
+
// payload.identifier, payload.access_token, payload.refresh_token (if API returns them)
|
|
273
|
+
myApp.saveSession(payload.access_token);
|
|
274
|
+
instance.unmount();
|
|
275
|
+
myApp.redirectToApp();
|
|
276
|
+
},
|
|
277
|
+
onContinue() {
|
|
278
|
+
instance.unmount();
|
|
279
|
+
myApp.redirectToApp();
|
|
280
|
+
},
|
|
281
|
+
onSignUp() { /* switch to signup */ },
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The backend should return token (and any session data) in the **final login API response** (e.g. `POST /login/custom`, `POST /otp/verify`, `POST /login/email/fr`, or social FR enroll). The SDK forwards that response into `payload` and into `getState().loginResult`.
|
|
286
|
+
|
|
287
|
+
### Instance API (returned by startSignup / startLogin)
|
|
288
|
+
|
|
289
|
+
```javascript
|
|
290
|
+
instance.unmount() // Remove the flow from DOM
|
|
291
|
+
instance.getState() // Read form data (email, mobile, userId, signupResult / loginResult, etc.)
|
|
292
|
+
instance.getCurrentStep() // Current step name
|
|
293
|
+
instance.getFlow() // FlowController reference
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Architecture
|
|
299
|
+
|
|
300
|
+
- **UI layer** (`sdk/ui/`) — Screens and layout, pure DOM
|
|
301
|
+
- **Core layer** (`sdk/core/`) — Flow, state, events; ready for API integration
|
|
302
|
+
- **Separation of concerns** — UI emits actions; core handles logic; APIs plug in later
|
|
303
|
+
|
|
304
|
+
## Lower-level embedding (mount / mountLogin)
|
|
305
|
+
|
|
306
|
+
If you prefer not to use `initializeAuth` / `startSignup` / `startLogin`, you can use the same underlying functions:
|
|
307
|
+
|
|
308
|
+
### 1. Include styles and mount
|
|
309
|
+
|
|
310
|
+
```html
|
|
311
|
+
<div id="signup-container"></div>
|
|
312
|
+
<link rel="stylesheet" href="/path/to/sdk/styles.css" />
|
|
313
|
+
<script type="module">
|
|
314
|
+
import { mount } from '/path/to/sdk/index.js';
|
|
315
|
+
const instance = mount('#signup-container');
|
|
316
|
+
</script>
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### 2. Mount options
|
|
320
|
+
|
|
321
|
+
```javascript
|
|
322
|
+
mount('#signup', {
|
|
323
|
+
env: 'local',
|
|
324
|
+
appIdentifier: 'control-center', // for social OAuth
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Entity is derived from email in the backend; no need to pass entity name/domain.
|
|
329
|
+
|
|
330
|
+
### 3. Login flow (lower-level)
|
|
331
|
+
|
|
332
|
+
```javascript
|
|
333
|
+
import { mountLogin } from '/path/to/sdk/index.js';
|
|
334
|
+
|
|
335
|
+
const loginInstance = mountLogin('#login-container', {
|
|
336
|
+
env: 'local',
|
|
337
|
+
appIdentifier: 'control-center',
|
|
338
|
+
loginMethods: { emailPassword: true, /* ... */ },
|
|
339
|
+
frsAsSecondFactor: true,
|
|
340
|
+
onSignUp() { /* switch to signup */ },
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 4. Integration with existing apps
|
|
345
|
+
|
|
346
|
+
- Use any container selector or `HTMLElement`
|
|
347
|
+
- No global pollution; all logic is scoped
|
|
348
|
+
- Styles use `wf-` prefix to avoid conflicts
|
|
349
|
+
|
|
350
|
+
## UI design rules
|
|
351
|
+
|
|
352
|
+
When adding or changing screens, follow **[DESIGN_RULES.md](DESIGN_RULES.md)** for tokens, typography, spacing, component patterns, and a new-screen checklist.
|
|
353
|
+
|
|
354
|
+
## File structure
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
sdk/
|
|
358
|
+
├── core/
|
|
359
|
+
│ ├── api.js # Central Auth API client (central_auth_collection.json)
|
|
360
|
+
│ ├── flow.js # Step navigation, flow type (standard/social)
|
|
361
|
+
│ ├── state.js # Form data
|
|
362
|
+
│ ├── login-config.js
|
|
363
|
+
│ ├── login-flow.js
|
|
364
|
+
│ ├── login-state.js
|
|
365
|
+
│ └── events.js # Event bus (optional)
|
|
366
|
+
├── ui/
|
|
367
|
+
│ ├── layout.js
|
|
368
|
+
│ ├── components.js
|
|
369
|
+
│ ├── screens/
|
|
370
|
+
│ │ ├── (signup screens)
|
|
371
|
+
│ │ └── login/
|
|
372
|
+
│ │ ├── entry.js, identifier-email.js, identifier-mobile.js
|
|
373
|
+
│ │ ├── password.js, otp.js, frs.js, success.js
|
|
374
|
+
│ │ └── index.js
|
|
375
|
+
│ └── screens/index.js
|
|
376
|
+
├── index.js # Main entry: initializeAuth, startSignup, startLogin, mount, mountLogin
|
|
377
|
+
├── auth.js # Public API: initializeAuth, startSignup, startLogin
|
|
378
|
+
├── signup.js # Sign-up flow: mount()
|
|
379
|
+
├── login.js # Login flow: mountLogin()
|
|
380
|
+
├── styles.css
|
|
381
|
+
└── README.md
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## API integration
|
|
385
|
+
|
|
386
|
+
APIs from `central_auth_collection.json` are wired in `core/api.js`. See [API_INTEGRATION.md](API_INTEGRATION.md) for endpoint mapping, options (`entityName`, `entityDomain`), and response assumptions (`user_id` from email verify).
|
package/auth.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central Auth SDK — Public API for host applications
|
|
3
|
+
* Exposes initializeAuth, startSignup, startLogin with configurable static parameters.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { resolveApiBaseUrl } from './core/env-config.js';
|
|
7
|
+
import { mount } from './signup.js';
|
|
8
|
+
import { mountLogin } from './login.js';
|
|
9
|
+
|
|
10
|
+
/** Default configuration stored after initializeAuth() */
|
|
11
|
+
let defaultConfig = {};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Merge config with defaults. Passed config overrides defaults.
|
|
15
|
+
* @param {Object} overrides - config passed to startSignup / startLogin
|
|
16
|
+
* @returns {Object} merged config
|
|
17
|
+
*/
|
|
18
|
+
function mergeConfig(overrides = {}) {
|
|
19
|
+
return {
|
|
20
|
+
...defaultConfig,
|
|
21
|
+
...overrides,
|
|
22
|
+
loginMethods: overrides.loginMethods != null
|
|
23
|
+
? { ...defaultConfig.loginMethods, ...overrides.loginMethods }
|
|
24
|
+
: defaultConfig.loginMethods,
|
|
25
|
+
social: overrides.social != null || (overrides.loginMethods && overrides.loginMethods.social != null)
|
|
26
|
+
? { ...defaultConfig.social, ...(overrides.social || overrides.loginMethods?.social || {}) }
|
|
27
|
+
: defaultConfig.social,
|
|
28
|
+
theme: overrides.theme != null
|
|
29
|
+
? { ...defaultConfig.theme, ...overrides.theme }
|
|
30
|
+
: defaultConfig.theme,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Resolve container: string selector or HTMLElement. Throws if missing/invalid.
|
|
36
|
+
* @param {string|HTMLElement} container
|
|
37
|
+
* @returns {HTMLElement}
|
|
38
|
+
*/
|
|
39
|
+
function resolveContainer(container) {
|
|
40
|
+
if (container == null) return null;
|
|
41
|
+
const el = typeof container === 'string' ? document.querySelector(container) : container;
|
|
42
|
+
return el && el.nodeType === 1 ? el : null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Initialize the SDK with optional default configuration.
|
|
47
|
+
* Call this once (e.g. at app load) to set shared defaults; startSignup/startLogin can override per call.
|
|
48
|
+
*
|
|
49
|
+
* @param {Object} config - Default static configuration
|
|
50
|
+
* @param {string} [config.env='local'] - Environment: 'local' | 'dev' | 'staging' | 'prod' — SDK uses the predefined API URL for that env
|
|
51
|
+
* @param {string} [config.appIdentifier] - Optional app identifier for OAuth / custom login; only sent when provided
|
|
52
|
+
* @param {string|HTMLElement} [config.defaultContainer] - Default container for rendering (can be overridden in start*)
|
|
53
|
+
* @param {Object} [config.loginMethods] - Default enabled login methods (see startLogin)
|
|
54
|
+
* @param {boolean} [config.frsAsSecondFactor] - Default for FRS as second factor (see startLogin)
|
|
55
|
+
* @param {boolean} [config.enableFaceRegistration=true] - Whether sign-up flow includes face registration step
|
|
56
|
+
* @param {Object} [config.theme] - Optional theme overrides (primaryColor, secondaryColor, backgroundColor, backgroundImage, cardColor, textColor, fontFamily, mode)
|
|
57
|
+
* @returns {{ startSignup: Function, startLogin: Function, getConfig: Function }}
|
|
58
|
+
*/
|
|
59
|
+
export function initializeAuth(config = {}) {
|
|
60
|
+
defaultConfig = {
|
|
61
|
+
env: 'local',
|
|
62
|
+
appIdentifier: undefined,
|
|
63
|
+
defaultContainer: null,
|
|
64
|
+
loginMethods: null,
|
|
65
|
+
frsAsSecondFactor: false,
|
|
66
|
+
enableFaceRegistration: true,
|
|
67
|
+
theme: null,
|
|
68
|
+
...config,
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
startSignup: startSignup,
|
|
72
|
+
startLogin: startLogin,
|
|
73
|
+
getConfig() {
|
|
74
|
+
return { ...defaultConfig };
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Start the Sign-Up flow. Renders into the given container and runs the signup wizard.
|
|
81
|
+
*
|
|
82
|
+
* @param {Object} config - Static configuration for this flow (merged with initializeAuth defaults)
|
|
83
|
+
* @param {string|HTMLElement} config.container - DOM selector or element where the SDK will render (required)
|
|
84
|
+
* @param {string} [config.env] - Environment: 'local' | 'dev' | 'staging' | 'prod' (default from init or 'local')
|
|
85
|
+
* @param {string} [config.appIdentifier] - Override app identifier
|
|
86
|
+
* @param {boolean} [config.enableFaceRegistration] - Include face registration step (default from init or true)
|
|
87
|
+
* @param {Function} [config.onSignupComplete] - Called when signup completes with (payload). Payload: email, mobile, userId, plus any token/fields from the final API response (e.g. access_token, refresh_token).
|
|
88
|
+
* @param {Function} [config.onContinue] - Called when user clicks Continue on the success screen (e.g. unmount and redirect).
|
|
89
|
+
* @param {Function} [config.onSwitchToLogin] - Called when user clicks "Sign in" (e.g. unmount signup and start login, e.g. login + FRS).
|
|
90
|
+
* @param {Function} [config.onBack] - Called when user clicks Back on the first screen (e.g. unmount and return to parent app).
|
|
91
|
+
* @param {Object} [config.theme] - Optional theme overrides (primaryColor, secondaryColor, backgroundColor, backgroundImage, cardColor, textColor, fontFamily, mode)
|
|
92
|
+
* @returns {{ unmount: Function, getState: Function, getFlow: Function, getCurrentStep: Function }|null} SDK instance or null if container invalid
|
|
93
|
+
*/
|
|
94
|
+
export function startSignup(config = {}) {
|
|
95
|
+
const merged = mergeConfig(config);
|
|
96
|
+
const container = config.container ?? merged.defaultContainer;
|
|
97
|
+
const el = resolveContainer(container);
|
|
98
|
+
if (!el) {
|
|
99
|
+
console.error('[Central Auth SDK] startSignup: container is required (pass config.container or set defaultContainer in initializeAuth)');
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const options = {
|
|
103
|
+
apiBaseUrl: resolveApiBaseUrl(merged),
|
|
104
|
+
appIdentifier: merged.appIdentifier,
|
|
105
|
+
enableFaceRegistration: merged.enableFaceRegistration,
|
|
106
|
+
theme: merged.theme || undefined,
|
|
107
|
+
onSignupComplete: config.onSignupComplete ?? merged.onSignupComplete,
|
|
108
|
+
onContinue: config.onContinue ?? merged.onContinue,
|
|
109
|
+
onSwitchToLogin: config.onSwitchToLogin ?? merged.onSwitchToLogin,
|
|
110
|
+
onBack: config.onBack ?? merged.onBack,
|
|
111
|
+
};
|
|
112
|
+
return mount(el, options);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Start the Login flow. Renders into the given container with configurable login methods.
|
|
117
|
+
*
|
|
118
|
+
* @param {Object} config - Static configuration for this flow (merged with initializeAuth defaults)
|
|
119
|
+
* @param {string|HTMLElement} config.container - DOM selector or element where the SDK will render (required)
|
|
120
|
+
* @param {string} [config.env] - Environment: 'local' | 'dev' | 'staging' | 'prod' (default from init or 'local')
|
|
121
|
+
* @param {string} [config.appIdentifier] - Override app identifier
|
|
122
|
+
* @param {Object} [config.loginMethods] - Which login methods are enabled
|
|
123
|
+
* @param {boolean} [config.loginMethods.emailPassword] - Email + Password
|
|
124
|
+
* @param {boolean} [config.loginMethods.mobilePassword] - Mobile + Password
|
|
125
|
+
* @param {boolean} [config.loginMethods.emailOtp] - Email + OTP
|
|
126
|
+
* @param {boolean} [config.loginMethods.mobileOtp] - Mobile + OTP
|
|
127
|
+
* @param {Object} [config.loginMethods.social] - Social login
|
|
128
|
+
* @param {boolean} [config.loginMethods.social.google] - Google
|
|
129
|
+
* @param {boolean} [config.loginMethods.social.microsoft] - Microsoft
|
|
130
|
+
* @param {boolean} [config.loginMethods.emailFrs] - Email + Face (FRS only)
|
|
131
|
+
* @param {boolean} [config.frsAsSecondFactor] - Require face verification after primary auth
|
|
132
|
+
* @param {Function} [config.onSignUp] - Callback when user clicks "Sign up" (e.g. switch to signup flow)
|
|
133
|
+
* @param {Function} [config.onLoginComplete] - Called when login completes with (payload). Payload: identifier, plus any token/fields from the final API response (e.g. access_token, refresh_token).
|
|
134
|
+
* @param {Function} [config.onContinue] - Called when user clicks Continue on the success screen (e.g. unmount and redirect).
|
|
135
|
+
* @param {Function} [config.onBack] - Called when user clicks Back on the first screen (e.g. unmount and return to parent app).
|
|
136
|
+
* @param {Object} [config.theme] - Optional theme overrides (primaryColor, secondaryColor, backgroundColor, backgroundImage, cardColor, textColor, fontFamily, mode)
|
|
137
|
+
* @returns {{ unmount: Function, getState: Function, getFlow: Function, getCurrentStep: Function }|null} SDK instance or null if container invalid
|
|
138
|
+
*/
|
|
139
|
+
export function startLogin(config = {}) {
|
|
140
|
+
const merged = mergeConfig(config);
|
|
141
|
+
const container = config.container ?? merged.defaultContainer;
|
|
142
|
+
const el = resolveContainer(container);
|
|
143
|
+
if (!el) {
|
|
144
|
+
console.error('[Central Auth SDK] startLogin: container is required (pass config.container or set defaultContainer in initializeAuth)');
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
const options = {
|
|
148
|
+
apiBaseUrl: resolveApiBaseUrl(merged),
|
|
149
|
+
appIdentifier: merged.appIdentifier,
|
|
150
|
+
loginMethods: merged.loginMethods,
|
|
151
|
+
frsAsSecondFactor: merged.frsAsSecondFactor,
|
|
152
|
+
theme: merged.theme || undefined,
|
|
153
|
+
onSignUp: config.onSignUp ?? merged.onSignUp,
|
|
154
|
+
onLoginComplete: config.onLoginComplete ?? merged.onLoginComplete,
|
|
155
|
+
onContinue: config.onContinue ?? merged.onContinue,
|
|
156
|
+
onBack: config.onBack ?? merged.onBack,
|
|
157
|
+
};
|
|
158
|
+
return mountLogin(el, options);
|
|
159
|
+
}
|