@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 +234 -222
- package/dist/sa-widgets.mjs +2498 -1320
- package/dist/sa-widgets.umd.js +128 -4
- package/package.json +7 -3
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
|
|
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
|
|
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
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
|
107
|
-
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
|
138
|
-
|
|
139
|
-
| `
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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)
|