@strivacity/sdk-svelte 3.0.0-rc.0 → 3.0.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/CHANGELOG.md +16 -0
- package/README.md +358 -348
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
# 3.0.0 (2026-04-09)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- ⚠️ EmbeddedFlow implemented ([a0e3ad8](https://github.com/Strivacity/sdk-js/commit/a0e3ad8))
|
|
6
|
+
- ⚠️ NativeFlow entry function now returns an object instead of a string ([9a8942d](https://github.com/Strivacity/sdk-js/commit/9a8942d))
|
|
7
|
+
|
|
8
|
+
### ⚠️ Breaking Changes
|
|
9
|
+
|
|
10
|
+
- EmbeddedFlow implemented ([a0e3ad8](https://github.com/Strivacity/sdk-js/commit/a0e3ad8))
|
|
11
|
+
- NativeFlow entry function now returns an object instead of a string ([9a8942d](https://github.com/Strivacity/sdk-js/commit/9a8942d))
|
|
12
|
+
|
|
13
|
+
### 🧱 Updated Dependencies
|
|
14
|
+
|
|
15
|
+
- Updated sdk-core to 3.0.0
|
|
16
|
+
|
|
1
17
|
## 3.0.0-rc.0 (2026-02-18)
|
|
2
18
|
|
|
3
19
|
### 🚀 Features
|
package/README.md
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @strivacity/sdk-svelte
|
|
2
2
|
|
|
3
|
-
Svelte
|
|
3
|
+
A Svelte library that integrates Strivacity's policy-driven authentication journeys into your application using the OAuth 2.0 PKCE flow. Supports `redirect`, `popup`, `native`, and `embedded` modes.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
See our [Developer Portal](https://www.strivacity.com/learn-support/developer-hub) to get started with developing with the Strivacity product.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This SDK allows you to integrate Strivacity's policy-driven journeys into your Svelte application. It wraps the `@strivacity/sdk-core` library as a Svelte context provider and exposes a `useStrivacity` function that provides reactive authentication state and methods throughout your component tree. The SDK uses the OAuth 2.0 PKCE flow to authenticate with Strivacity. For detailed configuration options, available modes, and advanced usage refer to the [`@strivacity/sdk-core` documentation](https://github.com/Strivacity/sdk-js/blob/main/packages/sdk-core/README.md).
|
|
10
|
+
|
|
11
|
+
## Demo Application
|
|
12
|
+
|
|
13
|
+
- [Example app](https://github.com/Strivacity/sdk-js/tree/main/apps/svelte)
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Svelte: 5+
|
|
6
18
|
|
|
7
19
|
## Install
|
|
8
20
|
|
|
@@ -12,271 +24,299 @@ npm install @strivacity/sdk-svelte
|
|
|
12
24
|
|
|
13
25
|
## Usage
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
### Initialization
|
|
16
28
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Wrap your application with the `StyAuthProvider` component to provide authentication context to all child components:
|
|
29
|
+
Wrap your application with `StyAuthProvider` in your root layout:
|
|
20
30
|
|
|
21
31
|
```svelte
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
<!-- src/routes/+layout.svelte -->
|
|
33
|
+
<script>
|
|
34
|
+
import { StyAuthProvider } from '@strivacity/sdk-svelte';
|
|
35
|
+
|
|
36
|
+
const options = {
|
|
37
|
+
mode: 'redirect', // or 'popup', 'native', 'embedded'
|
|
38
|
+
issuer: 'https://<YOUR_DOMAIN>',
|
|
39
|
+
scopes: ['openid', 'profile'],
|
|
40
|
+
clientId: '<YOUR_CLIENT_ID>',
|
|
41
|
+
redirectUri: '<YOUR_REDIRECT_URI>',
|
|
42
|
+
};
|
|
33
43
|
</script>
|
|
34
44
|
|
|
35
45
|
<StyAuthProvider {options}>
|
|
36
|
-
<
|
|
46
|
+
<slot />
|
|
37
47
|
</StyAuthProvider>
|
|
38
48
|
```
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
In redirect mode, users are redirected to the identity provider's login page and then back to your application after authentication.
|
|
43
|
-
|
|
44
|
-
##### Login page example
|
|
50
|
+
Use the `useStrivacity` function in any component to access authentication state:
|
|
45
51
|
|
|
46
52
|
```svelte
|
|
47
|
-
<script
|
|
48
|
-
|
|
49
|
-
import { useStrivacity, type RedirectContext } from '@strivacity/sdk-svelte';
|
|
50
|
-
|
|
51
|
-
const { login } = useStrivacity<RedirectContext>();
|
|
53
|
+
<script>
|
|
54
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
login();
|
|
55
|
-
});
|
|
56
|
+
const { loading, isAuthenticated, idTokenClaims } = useStrivacity();
|
|
56
57
|
</script>
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
### Redirect / Popup mode
|
|
61
|
+
|
|
62
|
+
In `redirect` mode the user is taken to the identity provider in the same window; in `popup` mode authentication happens in a popup. Both are initiated the same way from code.
|
|
63
|
+
|
|
64
|
+
#### Login page example
|
|
60
65
|
|
|
61
66
|
```svelte
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
<!-- src/routes/login/+page.svelte -->
|
|
68
|
+
<script>
|
|
69
|
+
import { onMount } from 'svelte';
|
|
70
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
const { login } = useStrivacity();
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
await goto('/profile');
|
|
73
|
-
} catch (error) {
|
|
74
|
-
console.error('Error during callback handling:', error);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
74
|
+
onMount(() => {
|
|
75
|
+
login();
|
|
76
|
+
});
|
|
77
77
|
</script>
|
|
78
78
|
|
|
79
|
-
<
|
|
79
|
+
<section>
|
|
80
|
+
<h1>Redirecting...</h1>
|
|
81
|
+
</section>
|
|
80
82
|
```
|
|
81
83
|
|
|
82
|
-
|
|
84
|
+
#### Callback page example
|
|
85
|
+
|
|
86
|
+
The callback page handles the response from the identity provider. It calls `handleCallback()` and redirects to `/profile` on success:
|
|
83
87
|
|
|
84
88
|
```svelte
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
<!-- src/routes/callback/+page.svelte -->
|
|
90
|
+
<script>
|
|
91
|
+
import { onMount } from 'svelte';
|
|
92
|
+
import { goto } from '$app/navigation';
|
|
93
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
const { handleCallback } = useStrivacity();
|
|
90
96
|
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
onMount(async () => {
|
|
98
|
+
try {
|
|
99
|
+
await handleCallback();
|
|
100
|
+
await goto('/profile');
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('Error during callback handling:', error);
|
|
93
103
|
}
|
|
104
|
+
});
|
|
94
105
|
</script>
|
|
95
106
|
|
|
96
|
-
|
|
97
|
-
<h1>
|
|
98
|
-
|
|
99
|
-
{:else}
|
|
100
|
-
<p>Not authenticated</p>
|
|
101
|
-
{/if}
|
|
107
|
+
<section>
|
|
108
|
+
<h1>Logging in...</h1>
|
|
109
|
+
</section>
|
|
102
110
|
```
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
#### Profile page example
|
|
105
113
|
|
|
106
114
|
```svelte
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
<!-- src/routes/profile/+page.svelte -->
|
|
116
|
+
<script>
|
|
117
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
110
118
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
onMount(() => {
|
|
114
|
-
logout();
|
|
115
|
-
});
|
|
119
|
+
const { loading, isAuthenticated, accessToken, accessTokenExpired, accessTokenExpirationDate, idTokenClaims, refreshToken } = useStrivacity();
|
|
116
120
|
</script>
|
|
117
121
|
|
|
118
|
-
<
|
|
122
|
+
<section>
|
|
123
|
+
{#if $loading}
|
|
124
|
+
<h1>Loading...</h1>
|
|
125
|
+
{:else}
|
|
126
|
+
<dl>
|
|
127
|
+
<dt><strong>accessToken</strong></dt>
|
|
128
|
+
<dd><pre>{JSON.stringify($accessToken)}</pre></dd>
|
|
129
|
+
<dt><strong>refreshToken</strong></dt>
|
|
130
|
+
<dd><pre>{JSON.stringify($refreshToken)}</pre></dd>
|
|
131
|
+
<dt><strong>accessTokenExpired</strong></dt>
|
|
132
|
+
<dd><pre>{JSON.stringify($accessTokenExpired)}</pre></dd>
|
|
133
|
+
<dt><strong>accessTokenExpirationDate</strong></dt>
|
|
134
|
+
<dd><pre>{$accessTokenExpirationDate ? new Date($accessTokenExpirationDate * 1000).toLocaleString() : JSON.stringify(null)}</pre></dd>
|
|
135
|
+
<dt><strong>claims</strong></dt>
|
|
136
|
+
<dd><pre>{JSON.stringify($idTokenClaims, null, 2)}</pre></dd>
|
|
137
|
+
</dl>
|
|
138
|
+
{/if}
|
|
139
|
+
</section>
|
|
119
140
|
```
|
|
120
141
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
In popup mode, authentication happens in a popup window, allowing users to stay on the same page.
|
|
142
|
+
#### Logout page example
|
|
124
143
|
|
|
125
|
-
|
|
144
|
+
The `postLogoutRedirectUri` parameter is optional and specifies where users are redirected after logout. This URI must be configured in the Admin Console as an allowed post-logout redirect URI.
|
|
126
145
|
|
|
127
146
|
```svelte
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
<!-- src/routes/logout/+page.svelte -->
|
|
148
|
+
<script>
|
|
149
|
+
import { onMount } from 'svelte';
|
|
150
|
+
import { goto } from '$app/navigation';
|
|
151
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
152
|
+
|
|
153
|
+
const { isAuthenticated, logout } = useStrivacity();
|
|
154
|
+
|
|
155
|
+
onMount(async () => {
|
|
156
|
+
if ($isAuthenticated) {
|
|
157
|
+
await logout({ postLogoutRedirectUri: location.origin });
|
|
158
|
+
} else {
|
|
159
|
+
await goto('/');
|
|
141
160
|
}
|
|
161
|
+
});
|
|
142
162
|
</script>
|
|
143
163
|
|
|
144
|
-
<
|
|
164
|
+
<section>
|
|
165
|
+
<h1>Logging out...</h1>
|
|
166
|
+
</section>
|
|
145
167
|
```
|
|
146
168
|
|
|
147
|
-
|
|
169
|
+
#### Component example
|
|
170
|
+
|
|
171
|
+
```svelte
|
|
172
|
+
<script>
|
|
173
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
174
|
+
|
|
175
|
+
const { isAuthenticated, idTokenClaims, login, logout } = useStrivacity();
|
|
148
176
|
|
|
149
|
-
|
|
177
|
+
$: name = `${$idTokenClaims?.given_name} ${$idTokenClaims?.family_name}`;
|
|
178
|
+
</script>
|
|
179
|
+
|
|
180
|
+
{#if $isAuthenticated}
|
|
181
|
+
<div>
|
|
182
|
+
<div>Welcome, {name}!</div>
|
|
183
|
+
<button on:click={() => logout()}>Logout</button>
|
|
184
|
+
</div>
|
|
185
|
+
{:else}
|
|
186
|
+
<div>
|
|
187
|
+
<div>Not logged in</div>
|
|
188
|
+
<button on:click={() => login()}>Log in</button>
|
|
189
|
+
</div>
|
|
190
|
+
{/if}
|
|
191
|
+
```
|
|
150
192
|
|
|
151
|
-
|
|
193
|
+
### Native mode
|
|
152
194
|
|
|
153
|
-
|
|
195
|
+
In `native` mode the `StyLoginRenderer` component renders the authentication UI inline using your custom widget components. You can define custom components for each input type; see [Example widgets](https://github.com/Strivacity/sdk-js/tree/main/apps/svelte/src/components/widgets).
|
|
154
196
|
|
|
155
|
-
|
|
197
|
+
The example widgets use SCSS for styling and Luxon for date handling:
|
|
156
198
|
|
|
157
|
-
|
|
199
|
+
```bash
|
|
200
|
+
npm install sass luxon
|
|
201
|
+
npm install --save-dev @types/luxon
|
|
202
|
+
```
|
|
158
203
|
|
|
159
|
-
|
|
204
|
+
```js
|
|
205
|
+
import CheckboxWidget from './checkbox.widget.svelte';
|
|
206
|
+
import DateWidget from './date.widget.svelte';
|
|
207
|
+
import InputWidget from './input.widget.svelte';
|
|
208
|
+
import LayoutWidget from './layout.widget.svelte';
|
|
209
|
+
import MultiSelectWidget from './multiselect.widget.svelte';
|
|
210
|
+
import PasscodeWidget from './passcode.widget.svelte';
|
|
211
|
+
import LoadingWidget from './loading.widget.svelte';
|
|
212
|
+
import PasswordWidget from './password.widget.svelte';
|
|
213
|
+
import PhoneWidget from './phone.widget.svelte';
|
|
214
|
+
import SelectWidget from './select.widget.svelte';
|
|
215
|
+
import StaticWidget from './static.widget.svelte';
|
|
216
|
+
import SubmitWidget from './submit.widget.svelte';
|
|
217
|
+
|
|
218
|
+
export const widgets = {
|
|
219
|
+
checkbox: CheckboxWidget,
|
|
220
|
+
date: DateWidget,
|
|
221
|
+
input: InputWidget,
|
|
222
|
+
layout: LayoutWidget,
|
|
223
|
+
loading: LoadingWidget,
|
|
224
|
+
passcode: PasscodeWidget,
|
|
225
|
+
password: PasswordWidget,
|
|
226
|
+
phone: PhoneWidget,
|
|
227
|
+
select: SelectWidget,
|
|
228
|
+
multiSelect: MultiSelectWidget,
|
|
229
|
+
static: StaticWidget,
|
|
230
|
+
submit: SubmitWidget,
|
|
231
|
+
};
|
|
232
|
+
```
|
|
160
233
|
|
|
161
|
-
|
|
234
|
+
#### Login page example
|
|
162
235
|
|
|
163
|
-
|
|
236
|
+
The login page extracts `session_id` from the URL on load, cleans up the URL, and passes it to the renderer. When a `session_id` is present the renderer calls `startSession(sessionId)` to resume the existing flow instead of starting a new one.
|
|
164
237
|
|
|
165
238
|
```svelte
|
|
239
|
+
<!-- src/routes/login/+page.svelte -->
|
|
166
240
|
<script lang="ts">
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
import type { FallbackError, IdTokenClaims, LoginFlowState } from '@strivacity/sdk-svelte';
|
|
241
|
+
import { goto } from '$app/navigation';
|
|
242
|
+
import { StyLoginRenderer, type FallbackError, type LoginFlowState } from '@strivacity/sdk-svelte';
|
|
243
|
+
import { widgets } from '$lib/components/widgets';
|
|
171
244
|
|
|
172
|
-
|
|
245
|
+
let sessionId: string | null = null;
|
|
173
246
|
|
|
174
|
-
|
|
175
|
-
|
|
247
|
+
if (window.location.search !== '') {
|
|
248
|
+
const url = new URL(window.location.href);
|
|
249
|
+
sessionId = url.searchParams.get('session_id');
|
|
250
|
+
url.search = '';
|
|
251
|
+
history.replaceState({}, '', url.toString());
|
|
252
|
+
}
|
|
176
253
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
254
|
+
const onLogin = async () => {
|
|
255
|
+
await goto('/profile');
|
|
256
|
+
};
|
|
181
257
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const onLogin = async (claims?: IdTokenClaims | null) => {
|
|
187
|
-
console.log('Login successful:', claims);
|
|
188
|
-
await goto('/profile');
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Called when native flow cannot handle the authentication
|
|
193
|
-
* Falls back to redirect mode by navigating to the provided URL
|
|
194
|
-
* @param error - FallbackError containing the fallback URL and message
|
|
195
|
-
*/
|
|
196
|
-
const onFallback = (error: FallbackError) => {
|
|
197
|
-
if (error.url) {
|
|
198
|
-
console.log(`Fallback: ${error.url}`);
|
|
199
|
-
window.location.href = error.url.toString();
|
|
200
|
-
} else {
|
|
201
|
-
console.error(`FallbackError without URL: ${error.message}`);
|
|
202
|
-
alert(error);
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Called when an error occurs during the authentication process
|
|
208
|
-
* @param error - Error message describing what went wrong
|
|
209
|
-
*/
|
|
210
|
-
const onError = (error: string) => {
|
|
211
|
-
console.error(`Error: ${error}`);
|
|
258
|
+
const onFallback = (error: FallbackError) => {
|
|
259
|
+
if (error.url) {
|
|
260
|
+
window.location.href = error.url.toString();
|
|
261
|
+
} else {
|
|
212
262
|
alert(error);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const onBlockReady = ({ previousState, state }: { previousState: LoginFlowState; state: LoginFlowState }) => {
|
|
229
|
-
console.log('previousState', previousState);
|
|
230
|
-
console.log('state', state);
|
|
231
|
-
};
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const onError = (error: string) => {
|
|
267
|
+
alert(error);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const onGlobalMessage = (message: string) => {
|
|
271
|
+
alert(message);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const onBlockReady = ({ previousState, state }: { previousState: LoginFlowState; state: LoginFlowState }) => {
|
|
275
|
+
console.log('previousState', previousState);
|
|
276
|
+
console.log('state', state);
|
|
277
|
+
};
|
|
232
278
|
</script>
|
|
233
279
|
|
|
234
280
|
<StyLoginRenderer
|
|
235
281
|
{widgets}
|
|
236
282
|
{sessionId}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
283
|
+
on:login={onLogin}
|
|
284
|
+
on:fallback={({ detail }) => onFallback(detail)}
|
|
285
|
+
on:error={({ detail }) => onError(detail)}
|
|
286
|
+
on:globalMessage={({ detail }) => onGlobalMessage(detail)}
|
|
287
|
+
on:blockReady={({ detail }) => onBlockReady(detail)}
|
|
242
288
|
/>
|
|
243
289
|
```
|
|
244
290
|
|
|
245
|
-
|
|
291
|
+
#### Callback page example
|
|
246
292
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
This component is essential for handling social login providers (like Google, Facebook, etc.) that require redirect-based authentication even within native mode flows.
|
|
293
|
+
When a `session_id` is present in the URL the native flow is resumed by forwarding it to the login page. Otherwise the standard `handleCallback()` path is used:
|
|
250
294
|
|
|
251
295
|
```svelte
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
await goto(
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
await handleCallback();
|
|
274
|
-
await goto('/profile');
|
|
275
|
-
} catch (error) {
|
|
276
|
-
console.error('Error during callback handling:', error);
|
|
277
|
-
}
|
|
296
|
+
<!-- src/routes/callback/+page.svelte -->
|
|
297
|
+
<script>
|
|
298
|
+
import { onMount } from 'svelte';
|
|
299
|
+
import { goto } from '$app/navigation';
|
|
300
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
301
|
+
|
|
302
|
+
const query = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
303
|
+
const { handleCallback } = useStrivacity();
|
|
304
|
+
|
|
305
|
+
onMount(async () => {
|
|
306
|
+
const url = new URL(location.href);
|
|
307
|
+
const sessionId = url.searchParams.get('session_id');
|
|
308
|
+
|
|
309
|
+
if (sessionId) {
|
|
310
|
+
await goto(`/login?session_id=${sessionId}`);
|
|
311
|
+
} else {
|
|
312
|
+
try {
|
|
313
|
+
await handleCallback();
|
|
314
|
+
await goto('/profile');
|
|
315
|
+
} catch (error) {
|
|
316
|
+
console.error('Error during callback handling:', error);
|
|
278
317
|
}
|
|
279
|
-
}
|
|
318
|
+
}
|
|
319
|
+
});
|
|
280
320
|
</script>
|
|
281
321
|
|
|
282
322
|
{#if query.error}
|
|
@@ -294,47 +334,102 @@ This component is essential for handling social login providers (like Google, Fa
|
|
|
294
334
|
{/if}
|
|
295
335
|
```
|
|
296
336
|
|
|
297
|
-
|
|
337
|
+
#### Entry page example
|
|
338
|
+
|
|
339
|
+
The entry page processes flows started by an external process (e.g. password reset) by calling `entry()` to extract the necessary parameters to resume the flow and forwarding them to the callback page:
|
|
340
|
+
|
|
341
|
+
```svelte
|
|
342
|
+
<!-- src/routes/entry/+page.svelte -->
|
|
343
|
+
<script>
|
|
344
|
+
import { onMount } from 'svelte';
|
|
345
|
+
import { goto } from '$app/navigation';
|
|
346
|
+
import { useStrivacity } from '@strivacity/sdk-svelte';
|
|
347
|
+
|
|
348
|
+
const { entry } = useStrivacity();
|
|
349
|
+
|
|
350
|
+
onMount(async () => {
|
|
351
|
+
try {
|
|
352
|
+
const data = await entry();
|
|
353
|
+
|
|
354
|
+
if (data && Object.keys(data).length > 0) {
|
|
355
|
+
await goto(`/callback?${new URLSearchParams(data).toString()}`);
|
|
356
|
+
} else {
|
|
357
|
+
await goto('/');
|
|
358
|
+
}
|
|
359
|
+
} catch (error) {
|
|
360
|
+
console.error('Entry failed:', error);
|
|
361
|
+
await goto('/');
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
</script>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
#### Profile page example
|
|
298
368
|
|
|
299
369
|
Same as the profile page example in redirect/popup mode.
|
|
300
370
|
|
|
301
|
-
|
|
371
|
+
#### Logout page example
|
|
302
372
|
|
|
303
373
|
Same as the logout page example in redirect/popup mode.
|
|
304
374
|
|
|
375
|
+
### Embedded mode
|
|
376
|
+
|
|
377
|
+
In `embedded` mode the `<sty-login>` web component (loaded via `bundle.js` from the cluster) handles rendering. Import the bundle at application startup to register the Strivacity web components:
|
|
378
|
+
|
|
379
|
+
```svelte
|
|
380
|
+
<!-- src/routes/+layout.svelte -->
|
|
381
|
+
<script>
|
|
382
|
+
import { onMount } from 'svelte';
|
|
383
|
+
import { StyAuthProvider } from '@strivacity/sdk-svelte';
|
|
384
|
+
|
|
385
|
+
onMount(() => {
|
|
386
|
+
void import(`${import.meta.env.VITE_ISSUER}/assets/components/bundle.js`);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
const options = {
|
|
390
|
+
mode: 'embedded',
|
|
391
|
+
issuer: 'https://<YOUR_DOMAIN>',
|
|
392
|
+
scopes: ['openid', 'profile'],
|
|
393
|
+
clientId: '<YOUR_CLIENT_ID>',
|
|
394
|
+
redirectUri: '<YOUR_REDIRECT_URI>',
|
|
395
|
+
};
|
|
396
|
+
</script>
|
|
397
|
+
|
|
398
|
+
<StyAuthProvider {options}>
|
|
399
|
+
<slot />
|
|
400
|
+
</StyAuthProvider>
|
|
401
|
+
```
|
|
402
|
+
|
|
305
403
|
## Logging
|
|
306
404
|
|
|
307
405
|
The SDK supports optional logging to help you debug authentication flows and monitor SDK behavior. You can enable the built-in console logger or provide your own custom logger implementation.
|
|
308
406
|
|
|
309
407
|
### Using the Default Logger
|
|
310
408
|
|
|
311
|
-
Enable the default console logger by adding the `logging` option
|
|
409
|
+
Enable the default console logger by adding the `logging` option:
|
|
312
410
|
|
|
313
411
|
```svelte
|
|
314
|
-
<script
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
};
|
|
412
|
+
<script>
|
|
413
|
+
import { StyAuthProvider, DefaultLogging } from '@strivacity/sdk-svelte';
|
|
414
|
+
|
|
415
|
+
const options = {
|
|
416
|
+
mode: 'redirect',
|
|
417
|
+
issuer: 'https://<YOUR_DOMAIN>',
|
|
418
|
+
scopes: ['openid', 'profile'],
|
|
419
|
+
clientId: '<YOUR_CLIENT_ID>',
|
|
420
|
+
redirectUri: '<YOUR_REDIRECT_URI>',
|
|
421
|
+
logging: DefaultLogging,
|
|
422
|
+
};
|
|
326
423
|
</script>
|
|
327
424
|
|
|
328
425
|
<StyAuthProvider {options}>
|
|
329
|
-
<
|
|
426
|
+
<slot />
|
|
330
427
|
</StyAuthProvider>
|
|
331
428
|
```
|
|
332
429
|
|
|
333
|
-
The default logger writes to the browser console and automatically prefixes messages with a correlation ID when available (via the `xEventId` property).
|
|
334
|
-
|
|
335
430
|
### Creating a Custom Logger
|
|
336
431
|
|
|
337
|
-
|
|
432
|
+
Implement the `SDKLogging` interface and pass your class to the `logging` option:
|
|
338
433
|
|
|
339
434
|
```typescript
|
|
340
435
|
import type { SDKLogging } from '@strivacity/sdk-svelte';
|
|
@@ -343,7 +438,6 @@ export class MyLogger implements SDKLogging {
|
|
|
343
438
|
xEventId?: string;
|
|
344
439
|
|
|
345
440
|
debug(message: string): void {
|
|
346
|
-
// Send to your logging pipeline
|
|
347
441
|
console.debug(this.xEventId ? `[${this.xEventId}] ${message}` : message);
|
|
348
442
|
}
|
|
349
443
|
|
|
@@ -361,39 +455,7 @@ export class MyLogger implements SDKLogging {
|
|
|
361
455
|
}
|
|
362
456
|
```
|
|
363
457
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
```svelte
|
|
367
|
-
<script lang="ts">
|
|
368
|
-
import { StyAuthProvider, type SDKOptions } from '@strivacity/sdk-svelte';
|
|
369
|
-
import { MyLogger } from './logging/MyLogger';
|
|
370
|
-
import Router from './Router.svelte';
|
|
371
|
-
|
|
372
|
-
const options: SDKOptions = {
|
|
373
|
-
mode: 'redirect',
|
|
374
|
-
issuer: 'https://<YOUR_DOMAIN>',
|
|
375
|
-
scopes: ['openid', 'profile'],
|
|
376
|
-
clientId: '<YOUR_CLIENT_ID>',
|
|
377
|
-
redirectUri: '<YOUR_REDIRECT_URI>',
|
|
378
|
-
logging: MyLogger, // Use your custom logger
|
|
379
|
-
};
|
|
380
|
-
</script>
|
|
381
|
-
|
|
382
|
-
<StyAuthProvider {options}>
|
|
383
|
-
<Router />
|
|
384
|
-
</StyAuthProvider>
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
### Logger Interface
|
|
388
|
-
|
|
389
|
-
The `SDKLogging` interface requires the following methods:
|
|
390
|
-
|
|
391
|
-
- **`debug(message: string): void`** - Log debug-level messages
|
|
392
|
-
- **`info(message: string): void`** - Log informational messages
|
|
393
|
-
- **`warn(message: string): void`** - Log warning messages
|
|
394
|
-
- **`error(message: string, error: Error): void`** - Log error messages with error objects
|
|
395
|
-
|
|
396
|
-
The optional `xEventId` property, when set by the SDK, provides a correlation ID to trace related log messages across the authentication flow.
|
|
458
|
+
The `SDKLogging` interface requires `debug`, `info`, `warn`, and `error` methods. The optional `xEventId` property, when set by the SDK, provides a correlation ID to trace related log messages across the authentication flow.
|
|
397
459
|
|
|
398
460
|
## API Documentation
|
|
399
461
|
|
|
@@ -403,142 +465,90 @@ The optional `xEventId` property, when set by the SDK, provides a correlation ID
|
|
|
403
465
|
useStrivacity<T extends PopupContext | RedirectContext | NativeContext>(): T;
|
|
404
466
|
```
|
|
405
467
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
**Properties**
|
|
468
|
+
The function returns a different context type depending on the `mode` configured in `StyAuthProvider`.
|
|
409
469
|
|
|
410
|
-
|
|
470
|
+
**Shared properties (all modes)**
|
|
411
471
|
|
|
412
|
-
- **`sdk: RedirectFlow | PopupFlow | NativeFlow`**:
|
|
413
|
-
- **`loading: Readable<boolean>`**:
|
|
414
|
-
- **`options: SDKOptions`**: The configured options
|
|
415
|
-
- **`isAuthenticated: Readable<boolean>`**:
|
|
416
|
-
- **`idTokenClaims: Readable<IdTokenClaims | null>`**: Claims from the ID token, or null if not
|
|
417
|
-
- **`accessToken: Readable<string | null>`**: The access token
|
|
418
|
-
- **`refreshToken: Readable<string | null>`**: The refresh token
|
|
419
|
-
- **`accessTokenExpired: Readable<boolean>`**:
|
|
420
|
-
- **`accessTokenExpirationDate: Readable<number | null>`**: Expiration
|
|
472
|
+
- **`sdk: RedirectFlow | PopupFlow | NativeFlow`**: The underlying SDK flow instance.
|
|
473
|
+
- **`loading: Readable<boolean>`**: `true` while the session is being initialized.
|
|
474
|
+
- **`options: SDKOptions`**: The configured SDK options.
|
|
475
|
+
- **`isAuthenticated: Readable<boolean>`**: `true` when the user has a valid session.
|
|
476
|
+
- **`idTokenClaims: Readable<IdTokenClaims | null>`**: Claims from the ID token, or `null` if not authenticated.
|
|
477
|
+
- **`accessToken: Readable<string | null>`**: The current access token.
|
|
478
|
+
- **`refreshToken: Readable<string | null>`**: The current refresh token.
|
|
479
|
+
- **`accessTokenExpired: Readable<boolean>`**: `true` when the access token has expired.
|
|
480
|
+
- **`accessTokenExpirationDate: Readable<number | null>`**: Expiration timestamp (Unix seconds) of the access token.
|
|
421
481
|
|
|
422
482
|
---
|
|
423
483
|
|
|
424
484
|
**Type: `RedirectContext`**
|
|
425
485
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
- **`
|
|
429
|
-
|
|
430
|
-
- **`
|
|
431
|
-
|
|
432
|
-
- **`
|
|
433
|
-
- **`revoke(): Promise<void>`**: Revokes the current session tokens using a redirect flow.
|
|
434
|
-
- **`logout(options?: LogoutOptions): Promise<void>`**: Logs out the user by redirecting to the identity provider.
|
|
435
|
-
- `options` (optional): Configuration options for logout.
|
|
436
|
-
- **`handleCallback(url?: string): Promise<void>`**: Handles the callback after a redirect-based authentication or token exchange.
|
|
437
|
-
- `url` (optional): The URL to handle for the callback.
|
|
486
|
+
- **`login(options?: LoginOptions): Promise<void>`**: Initiates login by redirecting to the identity provider.
|
|
487
|
+
- **`register(options?: RegisterOptions): Promise<void>`**: Initiates registration using a redirect flow.
|
|
488
|
+
- **`refresh(): Promise<void>`**: Refreshes the user's session.
|
|
489
|
+
- **`revoke(): Promise<void>`**: Revokes the current session tokens.
|
|
490
|
+
- **`logout(options?: LogoutOptions): Promise<void>`**: Logs the user out via redirect.
|
|
491
|
+
- **`handleCallback(url?: string): Promise<void>`**: Processes the authorization callback after redirect.
|
|
492
|
+
- **`entry(): Promise<Record<string, string>>`**: Processes an externally-initiated flow URL and returns the parameters needed to resume the flow.
|
|
438
493
|
|
|
439
494
|
---
|
|
440
495
|
|
|
441
496
|
**Type: `PopupContext`**
|
|
442
497
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
- **`
|
|
446
|
-
|
|
447
|
-
- **`
|
|
448
|
-
|
|
449
|
-
- **`
|
|
450
|
-
- **`revoke(): Promise<void>`**: Revokes the current session tokens using a popup flow.
|
|
451
|
-
- **`logout(options?: LogoutOptions): Promise<void>`**: Logs out the user using a popup window.
|
|
452
|
-
- `options` (optional): Configuration options for logout.
|
|
453
|
-
- **`handleCallback(url?: string): Promise<void>`**: Handles the callback after a popup-based authentication or token exchange.
|
|
454
|
-
- `url` (optional): The URL to handle for the callback.
|
|
498
|
+
- **`login(options?: LoginOptions): Promise<void>`**: Initiates login using a popup window.
|
|
499
|
+
- **`register(options?: RegisterOptions): Promise<void>`**: Initiates registration using a popup.
|
|
500
|
+
- **`refresh(): Promise<void>`**: Refreshes the user's session.
|
|
501
|
+
- **`revoke(): Promise<void>`**: Revokes the current session tokens.
|
|
502
|
+
- **`logout(options?: LogoutOptions): Promise<void>`**: Logs the user out via popup.
|
|
503
|
+
- **`handleCallback(url?: string): Promise<void>`**: Processes the authorization callback.
|
|
504
|
+
- **`entry(): Promise<Record<string, string>>`**: Processes an externally-initiated flow URL.
|
|
455
505
|
|
|
456
506
|
---
|
|
457
507
|
|
|
458
508
|
**Type: `NativeContext`**
|
|
459
509
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
- **`login(options?: LoginOptions): Promise<NativeFlowHandler>`**: Initiates the login process using a native flow.
|
|
463
|
-
- `options` (optional): Configuration options for login.
|
|
464
|
-
- **`register(options?: RegisterOptions): Promise<NativeFlowHandler>`**: Registers a new user using a native flow.
|
|
465
|
-
- `options` (optional): Configuration options for registration.
|
|
510
|
+
- **`login(options?: LoginOptions): Promise<NativeFlowHandler>`**: Initiates login using the native flow.
|
|
511
|
+
- **`register(options?: RegisterOptions): Promise<NativeFlowHandler>`**: Initiates registration using the native flow.
|
|
466
512
|
- **`refresh(): Promise<void>`**: Refreshes the user's session.
|
|
467
513
|
- **`revoke(): Promise<void>`**: Revokes the current session tokens.
|
|
468
|
-
- **`logout(options?: LogoutOptions): Promise<void>`**: Logs
|
|
469
|
-
|
|
470
|
-
- **`
|
|
471
|
-
- `url` (optional): The URL to handle for the callback.
|
|
472
|
-
|
|
473
|
-
### `StyLoginRenderer` component
|
|
474
|
-
|
|
475
|
-
The `StyLoginRenderer` component is used in native mode to render the authentication UI directly within your application. It provides a fully customizable login experience using your own UI components.
|
|
476
|
-
|
|
477
|
-
```typescript
|
|
478
|
-
StyLoginRenderer: Svelte.Component<{
|
|
479
|
-
params?: NativeParams;
|
|
480
|
-
widgets?: PartialRecord<WidgetType, Svelte.Component>;
|
|
481
|
-
sessionId?: string | null;
|
|
482
|
-
onlogin?: (claims?: IdTokenClaims | null) => void;
|
|
483
|
-
onfallback?: (error: FallbackError) => void;
|
|
484
|
-
onerror?: (error: any) => void;
|
|
485
|
-
onglobalmessage?: (message: string) => void;
|
|
486
|
-
onblockready?: ({ previousState, state }: { previousState: LoginFlowState; state: LoginFlowState }) => void;
|
|
487
|
-
}>;
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
**Properties**
|
|
491
|
-
|
|
492
|
-
- **`params?: NativeParams`** (optional): Additional parameters to pass to the native login flow. These parameters can include custom configuration options for the authentication process.
|
|
493
|
-
|
|
494
|
-
- **`widgets?: PartialRecord<WidgetType, Svelte.Component>`** (optional): A collection of Svelte components that define the UI widgets used in the authentication flow. Each widget type (input, button, layout, etc.) can be customized with your own components.
|
|
514
|
+
- **`logout(options?: LogoutOptions): Promise<void>`**: Logs the user out via redirect.
|
|
515
|
+
- **`handleCallback(url?: string): Promise<void>`**: Processes the authorization callback.
|
|
516
|
+
- **`entry(): Promise<Record<string, string>>`**: Processes an externally-initiated flow URL.
|
|
495
517
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
**Callback Props**
|
|
518
|
+
---
|
|
499
519
|
|
|
500
|
-
|
|
520
|
+
### `StyLoginRenderer` component
|
|
501
521
|
|
|
502
|
-
|
|
522
|
+
Used in `native` mode to render the authentication UI with your own widget components.
|
|
503
523
|
|
|
504
|
-
|
|
524
|
+
**Props**
|
|
505
525
|
|
|
506
|
-
- **`
|
|
526
|
+
- **`params?: NativeParams`**: Additional parameters for the native login flow.
|
|
527
|
+
- **`widgets?: PartialRecord<WidgetType, SvelteComponent>`**: Custom Svelte components for each widget type used in the flow.
|
|
528
|
+
- **`sessionId?: string | null`**: Session ID for resuming an existing authentication session.
|
|
507
529
|
|
|
508
|
-
|
|
530
|
+
**Events**
|
|
509
531
|
|
|
510
|
-
- **`
|
|
532
|
+
- **`on:login`**: Dispatched on successful authentication. Receives `IdTokenClaims | null`.
|
|
533
|
+
- **`on:fallback`**: Dispatched when the native flow needs to fall back to redirect. Receives `FallbackError` with a fallback URL.
|
|
534
|
+
- **`on:error`**: Dispatched when an error occurs during authentication.
|
|
535
|
+
- **`on:globalMessage`**: Dispatched when the flow wants to display a global message (e.g. account lockout warning).
|
|
536
|
+
- **`on:blockReady`**: Dispatched on flow state transitions. Receives `{ previousState: LoginFlowState; state: LoginFlowState }`. Useful for analytics and custom logging.
|
|
511
537
|
|
|
512
|
-
|
|
538
|
+
## Vulnerability Reporting
|
|
513
539
|
|
|
514
|
-
The
|
|
540
|
+
The [Guidelines for responsible disclosure](https://www.strivacity.com/report-a-security-issue) details the procedure for disclosing security issues. Please do not report security vulnerabilities on the public issue tracker.
|
|
515
541
|
|
|
516
|
-
|
|
517
|
-
- `close`: For close buttons
|
|
518
|
-
- `date`: For date input fields
|
|
519
|
-
- `input`: For text input fields
|
|
520
|
-
- `layout`: For layout containers and form structure
|
|
521
|
-
- `loading`: For loading indicators
|
|
522
|
-
- `multiSelect`: For multi-select dropdown fields
|
|
523
|
-
- `passcode`: For passcode input fields
|
|
524
|
-
- `password`: For password input fields
|
|
525
|
-
- `passkeyEnroll`: For passkey enrollment
|
|
526
|
-
- `passkeyLogin`: For passkey login
|
|
527
|
-
- `phone`: For phone number input fields
|
|
528
|
-
- `select`: For single-select dropdown fields
|
|
529
|
-
- `static`: For static text and display elements
|
|
530
|
-
- `submit`: For form submission buttons
|
|
531
|
-
- `webauthnEnroll`: For WebAuthn enrollment
|
|
532
|
-
- `webauthnLogin`: For WebAuthn login
|
|
542
|
+
## License
|
|
533
543
|
|
|
534
|
-
|
|
544
|
+
@strivacity/sdk-svelte is available under the MIT License. See the [LICENSE](https://github.com/Strivacity/sdk-js/blob/main/LICENSE) file for more info.
|
|
535
545
|
|
|
536
|
-
##
|
|
546
|
+
## Contributing
|
|
537
547
|
|
|
538
|
-
|
|
548
|
+
Please see our [contributing guide](https://github.com/Strivacity/sdk-js/blob/main/CONTRIBUTING.md).
|
|
539
549
|
|
|
540
550
|
## Migrating to v3.0
|
|
541
551
|
|
|
542
552
|
### Entry API Major Changes
|
|
543
553
|
|
|
544
|
-
Strivacity SDK's `entry()` API now returns a structured object instead of a plain string.
|
|
554
|
+
Strivacity SDK's `entry()` API now returns a structured object instead of a plain string. Check the example above in the usage section for more details.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strivacity/sdk-svelte",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Strivacity Svelte SDK client",
|
|
6
6
|
"author": "strivacity <opensource@strivacity.com>",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"url": "https://github.com/Strivacity/sdk-js"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@strivacity/sdk-core": "3.0.0
|
|
12
|
+
"@strivacity/sdk-core": "3.0.0"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"svelte": ">=5"
|