@masonitestudios/spartanauth-widgets 1.2.0 → 1.3.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,231 @@
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, 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, 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
+ - Emits a `spartan-login` CustomEvent on success with `{ token, transactionID }` in `event.detail`
61
+ - Stores the JWT in `localStorage` under `spartan-token`
62
+
63
+ **Custom loading overlay (slot):**
64
+
65
+ 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:
66
+
67
+ ```html
68
+ <spartan-login domain="..." sector="...">
69
+ <div slot="loading" style="display:flex;align-items:center;gap:8px;">
70
+ <my-spinner></my-spinner>
71
+ <span>Signing in…</span>
72
+ </div>
73
+ </spartan-login>
74
+ ```
75
+
76
+ The overlay container itself can be styled from outside the shadow DOM via the CSS part `loading-overlay`:
77
+
78
+ ```css
79
+ spartan-login::part(loading-overlay) {
80
+ background: rgba(0, 0, 0, 0.4);
81
+ border-radius: 4px;
82
+ }
83
+ ```
84
+
85
+ When no slot content is provided the overlay shows a plain "Loading…" text so existing integrations continue to work without any changes.
86
+
87
+ > **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.
88
+
89
+ ### Invite Widget
90
+
91
+ ```html
92
+ <spartan-invite
93
+ domain="https://auth.yourdomain.com"
94
+ sector="your-sector-id"
95
+ sub="user-sub-from-invite"
96
+ email="user@example.com"
97
+ locale="en"
98
+ redirect="/login">
99
+ </spartan-invite>
100
+ ```
101
+
102
+ **Attributes:**
103
+
104
+ | Attribute | Default | Description |
105
+ |---|---|---|
106
+ | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
107
+ | `sector` | *(admin sector)* | Sector ID |
108
+ | `sub` | `""` | User ID from the invitation (falls back to `?sub=` URL query param) |
109
+ | `email` | `""` | Invited user's email (displayed as context) |
110
+ | `locale` | `en` | UI language |
111
+ | `redirect` | `""` | URL to navigate to after successful registration |
112
+ | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
113
+
114
+ 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.
115
+
116
+ **Events:** Emits a `spartan-invite-complete` CustomEvent on success with `{ sub, success }` in `event.detail`.
117
+
118
+ ### Account Settings Widget
119
+
120
+ ```html
121
+ <spartan-account-settings
122
+ domain="https://auth.yourdomain.com"
123
+ sector="your-sector-id"
124
+ locale="en"
125
+ redirect="/"
126
+ show-web-authn="true"
127
+ show-totp="true"
128
+ show-skeleton="true"
129
+ redirect-on-unauthenticated="true">
130
+ </spartan-account-settings>
131
+ ```
132
+
133
+ **Attributes:**
134
+
135
+ | Attribute | Default | Description |
136
+ |---|---|---|
137
+ | `domain` | `http://127.0.0.1:11000` | SpartanAuth API base URL |
138
+ | `sector` | *(admin sector)* | Sector ID |
139
+ | `locale` | `en` | UI language |
140
+ | `redirect` | `/` | Redirect target (used when user is not authenticated) |
141
+ | `show-web-authn` | `true` | Show the passkey management section |
142
+ | `show-totp` | `true` | Show the authenticator-app section |
143
+ | `show-skeleton` | `false` | Show a placeholder until the first settings load finishes, then paint the sections once |
144
+ | `redirect-on-unauthenticated` | `true` | Automatically redirect unauthenticated users |
145
+ | `styles` | `""` | Custom CSS injected into the widget's shadow DOM |
146
+
147
+ **Features:**
148
+ - List, add, and remove WebAuthn passkeys
149
+ - List, add, validate, and remove MFA registrations (email & SMS OTP)
150
+ - 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
151
+ - MFA verification modal with one-time code input
152
+ - Reads the JWT from `localStorage` (`spartan-token`) for authenticated API calls
153
+
154
+ ## Styling
155
+
156
+ All widgets render inside Shadow DOM. To override internal styles, pass a CSS string via the `styles` attribute:
157
+
158
+ ```html
159
+ <spartan-login styles=".login-frame button { background-color: #00f000; }"></spartan-login>
160
+ ```
161
+
162
+ 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.
163
+
164
+ ## Internationalization
165
+
166
+ The widgets ship with translations for **English**, **French**, **Spanish**, and **Japanese** (`en`, `fr`, `es`, `ja`). Set the `locale` attribute to switch languages.
167
+
168
+ ## Project Structure
169
+
170
+ ```
171
+ library/ → Widget library (publishable package)
172
+ src/
173
+ components/
174
+ login-widget.tsx → <spartan-login>
175
+ invite-widget.tsx → <spartan-invite>
176
+ auth-settings.tsx → <spartan-account-settings>
177
+ spartanToken.ts → JWT helpers (localStorage)
178
+ banana.ts → i18n setup (banana-i18n)
179
+ i18n/ → Translation files (en, fr, es, ja)
180
+ App.tsx → Registers all widgets
181
+ index.tsx → Library entry point
182
+ vite.config.ts → Vite library build config
183
+
184
+ example/basic-app/ → Example app demonstrating all three widgets
185
+ index.html → Login & invite page
186
+ app.html → Protected page with account settings
187
+
188
+ mockup/ → Static HTML/CSS mockups for design reference
189
+ ```
190
+
191
+ ## Development
192
+
193
+ ### Prerequisites
194
+
195
+ - Node.js
196
+ - npm (or pnpm / yarn)
197
+
198
+ ### Library
199
+
200
+ ```bash
201
+ cd library
202
+ npm install
203
+ npm run build
204
+ ```
205
+
206
+ The build outputs to `library/dist/` as both UMD and ESM formats.
207
+
208
+ ### Example App
209
+
210
+ ```bash
211
+ cd example/basic-app
212
+ npm install
213
+ npm start
214
+ ```
215
+
216
+ Opens at [http://localhost:5173](http://localhost:5173). The example links to the library via a local file reference, so build the library first.
217
+
218
+ ## Key Dependencies
219
+
220
+ | Package | Purpose |
221
+ |---|---|
222
+ | [solid-js](https://www.solidjs.com/) | Reactive UI framework |
223
+ | [solid-element](https://github.com/solidjs/solid/tree/main/packages/solid-element) | Custom element wrapper for Solid components |
224
+ | [@github/webauthn-json](https://github.com/nicbarker/webauthn-json) | WebAuthn browser API helpers |
225
+ | [banana-i18n](https://github.com/nicbarker/banana-i18n) | MediaWiki-style i18n |
226
+ | [jwt-decode](https://github.com/nicbarker/jwt-decode) | JWT decoding for token expiry checks |
227
+ | [Vite](https://vitejs.dev/) | Build tool & dev server |
228
+
229
+ ## License
230
+
231
+ [Apache 2.0](LICENSE)