@masonitestudios/spartanauth-widgets 1.2.1 → 1.4.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/README.md CHANGED
@@ -1,222 +1,234 @@
1
- # SpartanAuth Widgets
2
-
3
- A collection of drop-in web components for authentication, built with [SolidJS](https://www.solidjs.com/) and packaged as custom elements using [`solid-element`](https://github.com/solidjs/solid/tree/main/packages/solid-element). These widgets connect to a [SpartanAuth](https://www.spartanauth.com) backend and can be embedded in any modern web application regardless of framework.
4
-
5
- ## Widgets
6
-
7
- | Custom Element | Description |
8
- |---|---|
9
- | `<spartan-login>` | Full login form supporting password, WebAuthn (passkeys), OTP/MFA, self-sign-up, and password reset flows |
10
- | `<spartan-invite>` | Invitation completion form — lets invited users set their password using a one-time code |
11
- | `<spartan-account-settings>` | Authenticated account settings panel for managing passkeys and MFA registrations (email & SMS) |
12
-
13
- ## Installation
14
-
15
- ```bash
16
- npm install @masonitestudios/spartanauth-widgets
17
- ```
18
-
19
- Then import the library in your project (this registers all three custom elements):
20
-
21
- ```js
22
- import '@masonitestudios/spartanauth-widgets';
23
- ```
24
-
25
- The library exposes both UMD (`dist/sa-widgets.umd.js`) and ES module (`dist/sa-widgets.mjs`) builds.
26
-
27
- ## Usage
28
-
29
- ### Login Widget
30
-
31
- ```html
32
- <spartan-login
33
- domain="https://auth.yourdomain.com"
34
- sector="your-sector-id"
35
- start-mode="password"
36
- locale="en"
37
- redirect="/app"
38
- styles="">
39
- </spartan-login>
40
- ```
41
-
42
- **Attributes:**
43
-
44
- | Attribute | Default | Description |
45
- |---|---|---|
46
- | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
47
- | `sector` | *(admin sector)* | Sector ID for your application |
48
- | `start-mode` | `password` | Initial login mode — `password` or `webauthn` |
49
- | `locale` | `en` | UI language (`en`, `fr`, `es`, `ja`) |
50
- | `redirect` | `""` | URL to navigate to after successful login |
51
- | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
52
-
53
- **Features:**
54
- - Password and WebAuthn (passkey) login
55
- - MFA / OTP challenge flow (email & SMS) with automatic registration picker when multiple methods are enrolled
56
- - Self-service sign-up (when enabled on the sector)
57
- - Password reset via emailed code
58
- - Emits a `spartan-login` CustomEvent on success with `{ token, transactionID }` in `event.detail`
59
- - Stores the JWT in `localStorage` under `spartan-token`
60
-
61
- **Custom loading overlay (slot):**
62
-
63
- During any loading state (form submission, social login, OAuth callback) an overlay covers the entire widget. You can inject your own loading animation using the named `loading` slot:
64
-
65
- ```html
66
- <spartan-login domain="..." sector="...">
67
- <div slot="loading" style="display:flex;align-items:center;gap:8px;">
68
- <my-spinner></my-spinner>
69
- <span>Signing in…</span>
70
- </div>
71
- </spartan-login>
72
- ```
73
-
74
- The overlay container itself can be styled from outside the shadow DOM via the CSS part `loading-overlay`:
75
-
76
- ```css
77
- spartan-login::part(loading-overlay) {
78
- background: rgba(0, 0, 0, 0.4);
79
- border-radius: 4px;
80
- }
81
- ```
82
-
83
- When no slot content is provided the overlay shows a plain "Loading…" text so existing integrations continue to work without any changes.
84
-
85
- > **OAuth callback note:** After a successful social login (OAuth code exchange) the widget stays in its loading state — rather than flashing back to the login form — so the host application has time to handle the `spartan-login` event and remove the element. If the element is not removed within 5 seconds the widget automatically returns to the login form as a fallback.
86
-
87
- ### Invite Widget
88
-
89
- ```html
90
- <spartan-invite
91
- domain="https://auth.yourdomain.com"
92
- sector="your-sector-id"
93
- sub="user-sub-from-invite"
94
- email="user@example.com"
95
- locale="en"
96
- redirect="/login">
97
- </spartan-invite>
98
- ```
99
-
100
- **Attributes:**
101
-
102
- | Attribute | Default | Description |
103
- |---|---|---|
104
- | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
105
- | `sector` | *(admin sector)* | Sector ID |
106
- | `sub` | `""` | User ID from the invitation (falls back to `?sub=` URL query param) |
107
- | `email` | `""` | Invited user's email (displayed as context) |
108
- | `locale` | `en` | UI language |
109
- | `redirect` | `""` | URL to navigate to after successful registration |
110
- | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
111
-
112
- The widget can also read the OTP code from the URL hash (e.g. `#invite?otp=ABC123`), making it easy to build one-click invite links.
113
-
114
- **Events:** Emits a `spartan-invite-complete` CustomEvent on success with `{ sub, success }` in `event.detail`.
115
-
116
- ### Account Settings Widget
117
-
118
- ```html
119
- <spartan-account-settings
120
- domain="https://auth.yourdomain.com"
121
- sector="your-sector-id"
122
- locale="en"
123
- redirect="/"
124
- show-web-authn="true"
125
- redirect-on-unauthenticated="true">
126
- </spartan-account-settings>
127
- ```
128
-
129
- **Attributes:**
130
-
131
- | Attribute | Default | Description |
132
- |---|---|---|
133
- | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
134
- | `sector` | *(admin sector)* | Sector ID |
135
- | `locale` | `en` | UI language |
136
- | `redirect` | `/` | Redirect target (used when user is not authenticated) |
137
- | `show-web-authn` | `true` | Show the passkey management section |
138
- | `redirect-on-unauthenticated` | `true` | Automatically redirect unauthenticated users |
139
- | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
140
-
141
- **Features:**
142
- - List, add, and remove WebAuthn passkeys
143
- - List, add, validate, and remove MFA registrations (email & SMS OTP)
144
- - MFA verification modal with one-time code input
145
- - Reads the JWT from `localStorage` (`spartan-token`) for authenticated API calls
146
-
147
- ## Styling
148
-
149
- All widgets render inside Shadow DOM. To override internal styles, pass a CSS string via the `styles` attribute:
150
-
151
- ```html
152
- <spartan-login styles=".login-frame button { background-color: #00f000; }"></spartan-login>
153
- ```
154
-
155
- ## Internationalization
156
-
157
- The widgets ship with translations for **English**, **French**, **Spanish**, and **Japanese** (`en`, `fr`, `es`, `ja`). Set the `locale` attribute to switch languages.
158
-
159
- ## Project Structure
160
-
161
- ```
162
- library/ → Widget library (publishable package)
163
- src/
164
- components/
165
- login-widget.tsx → <spartan-login>
166
- invite-widget.tsx → <spartan-invite>
167
- auth-settings.tsx → <spartan-account-settings>
168
- spartanToken.ts → JWT helpers (localStorage)
169
- banana.ts → i18n setup (banana-i18n)
170
- i18n/ → Translation files (en, fr, es, ja)
171
- App.tsx → Registers all widgets
172
- index.tsx → Library entry point
173
- vite.config.ts → Vite library build config
174
-
175
- example/basic-app/ → Example app demonstrating all three widgets
176
- index.html → Login & invite page
177
- app.html → Protected page with account settings
178
-
179
- mockup/ → Static HTML/CSS mockups for design reference
180
- ```
181
-
182
- ## Development
183
-
184
- ### Prerequisites
185
-
186
- - Node.js
187
- - npm (or pnpm / yarn)
188
-
189
- ### Library
190
-
191
- ```bash
192
- cd library
193
- npm install
194
- npm run build
195
- ```
196
-
197
- The build outputs to `library/dist/` as both UMD and ESM formats.
198
-
199
- ### Example App
200
-
201
- ```bash
202
- cd example/basic-app
203
- npm install
204
- npm start
205
- ```
206
-
207
- Opens at [http://localhost:5173](http://localhost:5173). The example links to the library via a local file reference, so build the library first.
208
-
209
- ## Key Dependencies
210
-
211
- | Package | Purpose |
212
- |---|---|
213
- | [solid-js](https://www.solidjs.com/) | Reactive UI framework |
214
- | [solid-element](https://github.com/solidjs/solid/tree/main/packages/solid-element) | Custom element wrapper for Solid components |
215
- | [@github/webauthn-json](https://github.com/nicbarker/webauthn-json) | WebAuthn browser API helpers |
216
- | [banana-i18n](https://github.com/nicbarker/banana-i18n) | MediaWiki-style i18n |
217
- | [jwt-decode](https://github.com/nicbarker/jwt-decode) | JWT decoding for token expiry checks |
218
- | [Vite](https://vitejs.dev/) | Build tool & dev server |
219
-
220
- ## License
221
-
222
- [Apache 2.0](LICENSE)
1
+ # SpartanAuth Widgets
2
+
3
+ A collection of drop-in web components for authentication, built with [SolidJS](https://www.solidjs.com/) and packaged as custom elements using [`solid-element`](https://github.com/solidjs/solid/tree/main/packages/solid-element). These widgets connect to a [SpartanAuth](https://www.spartanauth.com) backend and can be embedded in any modern web application regardless of framework.
4
+
5
+ ## Widgets
6
+
7
+ | Custom Element | Description |
8
+ |---|---|
9
+ | `<spartan-login>` | Full login form supporting password, WebAuthn (passkeys), email OTP, authenticator-app (TOTP) codes, self-sign-up, password reset, and a breached-password reset prompt |
10
+ | `<spartan-invite>` | Invitation completion form — lets invited users set their password using a one-time code |
11
+ | `<spartan-account-settings>` | Authenticated account settings panel for passwords, passkeys, email MFA, and authenticator apps |
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @masonitestudios/spartanauth-widgets
17
+ ```
18
+
19
+ Then import the library in your project (this registers all three custom elements):
20
+
21
+ ```js
22
+ import '@masonitestudios/spartanauth-widgets';
23
+ ```
24
+
25
+ The library exposes both UMD (`dist/sa-widgets.umd.js`) and ES module (`dist/sa-widgets.mjs`) builds.
26
+
27
+ ## Usage
28
+
29
+ ### Login Widget
30
+
31
+ ```html
32
+ <spartan-login
33
+ domain="https://auth.yourdomain.com"
34
+ sector="your-sector-id"
35
+ start-mode="password"
36
+ locale="en"
37
+ redirect="/app"
38
+ styles="">
39
+ </spartan-login>
40
+ ```
41
+
42
+ **Attributes:**
43
+
44
+ | Attribute | Default | Description |
45
+ |---|---|---|
46
+ | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
47
+ | `sector` | *(admin sector)* | Sector ID for your application |
48
+ | `start-mode` | `password` | Initial login mode — `password` or `webauthn` |
49
+ | `locale` | `en` | UI language (`en`, `fr`, `es`, `ja`) |
50
+ | `redirect` | `""` | URL to navigate to after successful login |
51
+ | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
52
+
53
+ **Features:**
54
+ - Password and WebAuthn (passkey) login
55
+ - MFA / OTP challenge flow (email) with a method picker when more than one second factor is enrolled
56
+ - Authenticator-app (TOTP) codes and one-time recovery codes
57
+ - Authenticator enrollment during sign-in when the sector requires MFA and the user has no second factor yet
58
+ - Self-service sign-up (when enabled on the sector)
59
+ - Password reset via emailed code
60
+ - When a sector requires a reset for a password already known to be breached, sign-in stops on that screen and emails a reset code. The widget does not store a session or continue to another factor
61
+ - Reset, invite, and sign-up show the server's breach and "could not check" messages instead of treating every rejection as a bad code or a generic failure
62
+ - Emits a `spartan-login` CustomEvent on success with `{ token, transactionID }` in `event.detail`
63
+ - Stores the JWT in `localStorage` under `spartan-token`
64
+
65
+ **Custom loading overlay (slot):**
66
+
67
+ During any loading state (form submission, social login, OAuth callback) an overlay covers the entire widget. You can inject your own loading animation using the named `loading` slot:
68
+
69
+ ```html
70
+ <spartan-login domain="..." sector="...">
71
+ <div slot="loading" style="display:flex;align-items:center;gap:8px;">
72
+ <my-spinner></my-spinner>
73
+ <span>Signing in…</span>
74
+ </div>
75
+ </spartan-login>
76
+ ```
77
+
78
+ The overlay container itself can be styled from outside the shadow DOM via the CSS part `loading-overlay`:
79
+
80
+ ```css
81
+ spartan-login::part(loading-overlay) {
82
+ background: rgba(0, 0, 0, 0.4);
83
+ border-radius: 4px;
84
+ }
85
+ ```
86
+
87
+ When no slot content is provided the overlay shows a plain "Loading…" text so existing integrations continue to work without any changes.
88
+
89
+ > **OAuth callback note:** After a successful social login (OAuth code exchange) the widget stays in its loading state — rather than flashing back to the login form — so the host application has time to handle the `spartan-login` event and remove the element. If the element is not removed within 5 seconds the widget automatically returns to the login form as a fallback.
90
+
91
+ ### Invite Widget
92
+
93
+ ```html
94
+ <spartan-invite
95
+ domain="https://auth.yourdomain.com"
96
+ sector="your-sector-id"
97
+ sub="user-sub-from-invite"
98
+ email="user@example.com"
99
+ locale="en"
100
+ redirect="/login">
101
+ </spartan-invite>
102
+ ```
103
+
104
+ **Attributes:**
105
+
106
+ | Attribute | Default | Description |
107
+ |---|---|---|
108
+ | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
109
+ | `sector` | *(admin sector)* | Sector ID |
110
+ | `sub` | `""` | User ID from the invitation (falls back to `?sub=` URL query param) |
111
+ | `email` | `""` | Invited user's email (displayed as context) |
112
+ | `locale` | `en` | UI language |
113
+ | `redirect` | `""` | URL to navigate to after successful registration |
114
+ | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
115
+
116
+ The widget can also read the OTP code from the URL hash (e.g. `#invite?otp=ABC123`), making it easy to build one-click invite links.
117
+
118
+ **Events:** Emits a `spartan-invite-complete` CustomEvent on success with `{ sub, success }` in `event.detail`.
119
+
120
+ ### Account Settings Widget
121
+
122
+ ```html
123
+ <spartan-account-settings
124
+ domain="https://auth.yourdomain.com"
125
+ sector="your-sector-id"
126
+ locale="en"
127
+ redirect="/"
128
+ show-web-authn="true"
129
+ show-totp="true"
130
+ show-skeleton="true"
131
+ redirect-on-unauthenticated="true">
132
+ </spartan-account-settings>
133
+ ```
134
+
135
+ **Attributes:**
136
+
137
+ | Attribute | Default | Description |
138
+ |---|---|---|
139
+ | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
140
+ | `sector` | *(admin sector)* | Sector ID |
141
+ | `locale` | `en` | UI language |
142
+ | `redirect` | `/` | Redirect target (used when user is not authenticated) |
143
+ | `show-web-authn` | `true` | Show the passkey management section |
144
+ | `show-totp` | `true` | Show the authenticator-app section |
145
+ | `show-skeleton` | `false` | Show a placeholder until the first settings load finishes, then paint the sections once |
146
+ | `redirect-on-unauthenticated` | `true` | Automatically redirect unauthenticated users |
147
+ | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
148
+
149
+ **Features:**
150
+ - Change the signed-in password. When that password is in a known breach, the panel shows a warning and can email a reset code
151
+ - List, add, and remove WebAuthn passkeys
152
+ - List, add, validate, and remove MFA registrations (email & SMS OTP)
153
+ - List, add, and remove authenticator apps. Setup shows a QR code and the shared secret once, then the one-time recovery codes the first time the user enrolls
154
+ - MFA verification modal with one-time code input
155
+ - Reads the JWT from `localStorage` (`spartan-token`) for authenticated API calls
156
+
157
+ ## Styling
158
+
159
+ All widgets render inside Shadow DOM. To override internal styles, pass a CSS string via the `styles` attribute:
160
+
161
+ ```html
162
+ <spartan-login styles=".login-frame button { background-color: #00f000; }"></spartan-login>
163
+ ```
164
+
165
+ The settings placeholder uses `.skeleton-line`, `.skeleton-block`, and `.skeleton-row`. Those classes do not share the table or button rules. Recolor the shimmer with `--skeleton-base` and `--skeleton-shine` if the defaults do not match the page.
166
+
167
+ ## Internationalization
168
+
169
+ The widgets ship with translations for **English**, **French**, **Spanish**, and **Japanese** (`en`, `fr`, `es`, `ja`). Set the `locale` attribute to switch languages.
170
+
171
+ ## Project Structure
172
+
173
+ ```
174
+ library/ → Widget library (publishable package)
175
+ src/
176
+ components/
177
+ login-widget.tsx → <spartan-login>
178
+ invite-widget.tsx → <spartan-invite>
179
+ auth-settings.tsx → <spartan-account-settings>
180
+ spartanToken.ts → JWT helpers (localStorage)
181
+ banana.ts → i18n setup (banana-i18n)
182
+ i18n/ → Translation files (en, fr, es, ja)
183
+ App.tsx → Registers all widgets
184
+ index.tsx → Library entry point
185
+ vite.config.ts → Vite library build config
186
+
187
+ example/basic-app/ → Example app demonstrating all three widgets
188
+ index.html → Login & invite page
189
+ app.html → Protected page with account settings
190
+
191
+ mockup/ → Static HTML/CSS mockups for design reference
192
+ ```
193
+
194
+ ## Development
195
+
196
+ ### Prerequisites
197
+
198
+ - Node.js
199
+ - npm (or pnpm / yarn)
200
+
201
+ ### Library
202
+
203
+ ```bash
204
+ cd library
205
+ npm install
206
+ npm run build
207
+ ```
208
+
209
+ The build outputs to `library/dist/` as both UMD and ESM formats.
210
+
211
+ ### Example App
212
+
213
+ ```bash
214
+ cd example/basic-app
215
+ npm install
216
+ npm start
217
+ ```
218
+
219
+ Opens at [http://localhost:5173](http://localhost:5173). The example links to the library via a local file reference, so build the library first.
220
+
221
+ ## Key Dependencies
222
+
223
+ | Package | Purpose |
224
+ |---|---|
225
+ | [solid-js](https://www.solidjs.com/) | Reactive UI framework |
226
+ | [solid-element](https://github.com/solidjs/solid/tree/main/packages/solid-element) | Custom element wrapper for Solid components |
227
+ | [@github/webauthn-json](https://github.com/nicbarker/webauthn-json) | WebAuthn browser API helpers |
228
+ | [banana-i18n](https://github.com/nicbarker/banana-i18n) | MediaWiki-style i18n |
229
+ | [jwt-decode](https://github.com/nicbarker/jwt-decode) | JWT decoding for token expiry checks |
230
+ | [Vite](https://vitejs.dev/) | Build tool & dev server |
231
+
232
+ ## License
233
+
234
+ [Apache 2.0](LICENSE)