@schibsted/account-sdk-browser 6.0.0-alpha.1 → 6.0.0-alpha.11
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 +55 -280
- package/dist/account-sdk.d.ts +22 -0
- package/dist/account.d.ts +179 -0
- package/dist/cache.d.ts +65 -0
- package/dist/compatibility/index.d.ts +2 -0
- package/dist/compatibility/install-legacy-compatibility.d.ts +10 -0
- package/dist/compatibility/legacy-identity.d.ts +29 -0
- package/dist/compatibility/legacy-monetization.d.ts +9 -0
- package/dist/compatibility/types.d.ts +40 -0
- package/dist/compatibility/warnings.d.ts +3 -0
- package/dist/compatibility.js +167 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/config.d.ts +86 -0
- package/dist/globals.d.ts +11 -0
- package/dist/has-access-response.d.ts +2 -0
- package/dist/identity.d.ts +302 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +782 -0
- package/dist/index.js.map +1 -0
- package/dist/monetization.d.ts +39 -0
- package/{src → dist}/object.d.ts +4 -9
- package/dist/popup.d.ts +9 -0
- package/dist/resolve-browser-window-X5jXljW9.js +55 -0
- package/dist/resolve-browser-window-X5jXljW9.js.map +1 -0
- package/dist/resolve-browser-window.d.ts +1 -0
- package/dist/rest-client.d.ts +102 -0
- package/dist/rest-clients.d.ts +10 -0
- package/dist/sdk-error.d.ts +29 -0
- package/dist/session-response.d.ts +54 -0
- package/dist/session-state.d.ts +13 -0
- package/{src/spidTalk.d.ts → dist/spid-talk.d.ts} +4 -6
- package/dist/types/account.d.ts +48 -0
- package/dist/types/common.d.ts +28 -0
- package/dist/types/identity.d.ts +23 -0
- package/dist/types/login.d.ts +125 -0
- package/dist/types/monetization.d.ts +26 -0
- package/dist/types/session.d.ts +146 -0
- package/dist/url.d.ts +8 -0
- package/dist/validate.d.ts +50 -0
- package/dist/version.d.ts +2 -0
- package/package.json +34 -25
- package/src/account-sdk.ts +92 -0
- package/src/account.ts +337 -0
- package/src/{cache.js → cache.ts} +53 -38
- package/src/compatibility/index.ts +10 -0
- package/src/compatibility/install-legacy-compatibility.ts +144 -0
- package/src/compatibility/legacy-identity.ts +220 -0
- package/src/compatibility/legacy-monetization.ts +30 -0
- package/src/compatibility/types.ts +76 -0
- package/src/compatibility/warnings.ts +28 -0
- package/src/{config.js → config.ts} +7 -32
- package/src/globals.ts +8 -0
- package/src/has-access-response.ts +35 -0
- package/src/identity.ts +1026 -0
- package/src/index.ts +40 -0
- package/src/monetization.ts +128 -0
- package/src/{object.js → object.ts} +9 -16
- package/src/popup.ts +74 -0
- package/src/resolve-browser-window.ts +11 -0
- package/src/rest-client.ts +253 -0
- package/src/rest-clients.ts +30 -0
- package/src/sdk-error.ts +61 -0
- package/src/session-response.ts +100 -0
- package/src/session-state.ts +20 -0
- package/src/{spidTalk.js → spid-talk.ts} +10 -12
- package/src/types/account.ts +55 -0
- package/src/types/common.ts +32 -0
- package/src/types/identity.ts +26 -0
- package/src/types/login.ts +150 -0
- package/src/types/monetization.ts +29 -0
- package/src/types/session.ts +169 -0
- package/src/{url.js → url.ts} +6 -10
- package/src/{validate.js → validate.ts} +27 -43
- package/src/{version.js → version.ts} +1 -2
- package/identity.d.ts +0 -1
- package/identity.js +0 -5
- package/index.d.ts +0 -4
- package/index.js +0 -9
- package/monetization.d.ts +0 -1
- package/monetization.js +0 -5
- package/payment.d.ts +0 -1
- package/payment.js +0 -5
- package/src/RESTClient.d.ts +0 -89
- package/src/RESTClient.js +0 -193
- package/src/SDKError.d.ts +0 -16
- package/src/SDKError.js +0 -55
- package/src/cache.d.ts +0 -64
- package/src/config.d.ts +0 -34
- package/src/global-registry.js +0 -20
- package/src/identity.d.ts +0 -679
- package/src/identity.js +0 -1154
- package/src/monetization.d.ts +0 -80
- package/src/monetization.js +0 -172
- package/src/payment.d.ts +0 -115
- package/src/payment.js +0 -211
- package/src/popup.d.ts +0 -10
- package/src/popup.js +0 -59
- package/src/url.d.ts +0 -10
- package/src/validate.d.ts +0 -64
- package/src/version.d.ts +0 -2
package/README.md
CHANGED
|
@@ -2,312 +2,87 @@
|
|
|
2
2
|
[](https://codecov.io/gh/schibsted/account-sdk-browser)
|
|
3
3
|
[](https://snyk.io/test/github/schibsted/account-sdk-browser)
|
|
4
4
|
|
|
5
|
-
# Schibsted
|
|
5
|
+
# Schibsted Account SDK for browsers
|
|
6
6
|
|
|
7
|
-
Welcome! This is the home of the Schibsted
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
products and subscriptions, etc.
|
|
7
|
+
Welcome! This is the home of the Schibsted Account JavaScript SDK for browsers. Use it to let users
|
|
8
|
+
sign up and log in with Schibsted Account, read the current session, and check access to products
|
|
9
|
+
and features.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
See the [public SDK documentation](https://schibsted.github.io/account-sdk-browser/) for setup,
|
|
12
|
+
integration guidance, and the API reference.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
domains (i.e. id.vg.no) to avoid Third-Party Cookie request.
|
|
14
|
+
## Before You Start
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
The SDK communicates mainly with Session Service on a brand domain such as `id.vg.no`. Your website
|
|
17
|
+
and Session Service domain must share the same top-level site so browser cookies are sent with XHR
|
|
18
|
+
requests.
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
For local development:
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
- serve your site over HTTPS, because Session Service is hosted over HTTPS
|
|
23
|
+
- use a local hostname with the same top-level site as the configured Session Service domain
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
syntax (including async/await and other ES2017 and WHATWG features). We recommend that you do
|
|
30
|
-
any transpilation yourself for the browser versions you need to cater to. We do not add polyfills.
|
|
31
|
-
4. Initiate the SDK and provide at least `clientId`, `env` and `sessionDomain`.
|
|
25
|
+
For example, if your pre-production site is `pre.sdk-example.com` and uses
|
|
26
|
+
`id.pre.sdk-example.com` as Session Service, use a local hostname such as
|
|
27
|
+
`local.sdk-example.com`.
|
|
32
28
|
|
|
33
|
-
If this is
|
|
34
|
-
[support](mailto:schibstedaccount@schibsted.com)
|
|
29
|
+
If this is a new site and you do not have a `sessionDomain` yet, contact
|
|
30
|
+
[support](mailto:schibstedaccount@schibsted.com).
|
|
35
31
|
|
|
36
|
-
##
|
|
32
|
+
## Development
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
## Simplified login widget
|
|
41
|
-
|
|
42
|
-
1. Ensure that your site has no site specific terms and conditions in the Schibsted account login flow.
|
|
43
|
-
1. Define rules for when and how often the simplified login prompt should be shown to unique users on your site. How you do this is up to you, but we recommend starting with showing the prompt once per user before potentially increasing this frequency over time.
|
|
44
|
-
1. Set up a function to check if users landing on your domain [is logged in](https://schibsted.github.io/account-sdk-browser/Identity.html#isLoggedIn) to your site.
|
|
45
|
-
1. If the user is not logged-in to your site, call the [showSimplifiedLoginWidget](https://schibsted.github.io/account-sdk-browser/Identity.html#showSimplifiedLoginWidget) function. The `showSimplifiedLoginWidget` accepts the same params as login function (`state` is required, it might be string or async function). If the simplified login prompt is to be loaded, `showSimplifiedLoginWidget` will return `true`.
|
|
46
|
-
1. Set up a way to store information about which users have been shown the simplified login prompt. How you do this is up to you, but one way is to use localStorage. Use this information to execute on the rules defined in #2.
|
|
47
|
-
|
|
48
|
-
## Example project
|
|
49
|
-
|
|
50
|
-
There is an example that demonstrates how the SDK can be used. The code is
|
|
51
|
-
[here](https://schibsted.ghe.com/user-identity/sdk-example), and you can see it live
|
|
52
|
-
[here](https://pro.sdk-example.com). You have a use-case that we haven't thought of? Ask us to add
|
|
53
|
-
it by creating an [issue](https://schibsted.ghe.com/user-identity/sdk-example/issues/new).
|
|
54
|
-
|
|
55
|
-
You can use that code as inspiration or just fork and play with it. The account-sdk-browser NPM
|
|
56
|
-
module is used for authenticating the user with Schibsted account. Take a look at how the SDK is
|
|
57
|
-
initialized.
|
|
58
|
-
|
|
59
|
-
When a user wants to log in to your site, you direct them to a UI flow hosted by **Schibsted Account**.
|
|
60
|
-
We authenticate the user and redirect them back to your site. This final redirect back to your site is performed in accordance with the OAuth2 specification.
|
|
61
|
-
This means we pass a `code` in the query string of that redirect URI.
|
|
62
|
-
You can use that `code` on your site's backend, along with your client credentials (client ID and secret), to obtain an *Access Token* (AT) and a *Refresh Token* (RT).
|
|
63
|
-
You should not send the AT (and **never** the RT!) to the browser. Instead, keep them on the server side and associate them with the specific user session.
|
|
64
|
-
This allows you to call Schibsted Account APIs on behalf of that user.
|
|
65
|
-
|
|
66
|
-
## Events
|
|
67
|
-
|
|
68
|
-
The SDK fires events on the instances when something we deem interesting is happening. For example the
|
|
69
|
-
[Identity](https://schibsted.github.io/account-sdk-browser/Identity.html) class
|
|
70
|
-
emits some events when the user is logged in or logged out. This SDK uses a familar interface that's
|
|
71
|
-
very similar to Node's [EventEmitter](https://nodejs.org/api/events.html). The most important
|
|
72
|
-
methods are `.on(eventName, listener)` (to subscribe to an event) and `.off(eventName, listener)`
|
|
73
|
-
(to unsubscribe to an event).
|
|
74
|
-
|
|
75
|
-
The SDK also emits global events on the `window` when a new instance is created.
|
|
76
|
-
Events are emitted for:
|
|
77
|
-
|
|
78
|
-
| Class | event name |
|
|
79
|
-
| ------------ | ----------------------- |
|
|
80
|
-
| Identity | `schIdentity:ready` |
|
|
81
|
-
| Monetization | `schMonetization:ready` |
|
|
82
|
-
| Payment | `schPayment:ready` |
|
|
83
|
-
|
|
84
|
-
```js
|
|
85
|
-
window.addEventListener('schIdentity:ready', e => {
|
|
86
|
-
// The event contains the initialized instance (e.detail.instance);
|
|
87
|
-
}
|
|
34
|
+
Install dependencies and run the standard checks:
|
|
88
35
|
|
|
36
|
+
```sh
|
|
37
|
+
npm ci
|
|
38
|
+
npm run build
|
|
39
|
+
npm test
|
|
40
|
+
npm run lint
|
|
41
|
+
npm run typecheck
|
|
89
42
|
```
|
|
90
43
|
|
|
91
|
-
##
|
|
92
|
-
|
|
93
|
-
Let's start with a bit of example code:
|
|
94
|
-
|
|
95
|
-
#### Example
|
|
96
|
-
|
|
97
|
-
```javascript
|
|
98
|
-
import { Identity } from '@schibsted/account-sdk-browser';
|
|
99
|
-
|
|
100
|
-
const identity = new Identity({
|
|
101
|
-
clientId: '56e9a5d1eee0000000000000',
|
|
102
|
-
redirectUri: 'https://awesomenews.site', // ensure it's listed in selfservice
|
|
103
|
-
env: 'PRE', // Schibsted account env. A url or a special key: 'PRE', 'PRO', 'PRO_NO', 'PRO_FI' or 'PRO_DK'
|
|
104
|
-
sessionDomain: 'https://id.awesomenews.site', // client-configured session-service domain
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
async function whenSiteLoaded() {
|
|
108
|
-
const loginContainer = document.getElementById('login-container');
|
|
109
|
-
if (await identity.isLoggedIn()) {
|
|
110
|
-
const user = await identity.getUser();
|
|
111
|
-
const span = document.createElement('span');
|
|
112
|
-
span.textContent = `Hello ${user.givenName}`;
|
|
113
|
-
loginContainer.appendChild(span);
|
|
114
|
-
} else {
|
|
115
|
-
loginContainer.innerHTML = '<button class="login-button">Log in</button>';
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function userClicksLogIn() {
|
|
120
|
-
identity.login({ state: 'some-random-string-1234-foobar-wonky-pig' });
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
#### Regarding `state`
|
|
125
|
-
|
|
126
|
-
This parameter is an OpenID Connect parameter (described in [this paragraph in the
|
|
127
|
-
spec](http://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.1)). It's formatted as
|
|
128
|
-
an opaque string. This means you can send anything that can be serialized to a string. In practice,
|
|
129
|
-
we have good experience sending something like a JSON value like a base64-url-encoded value — it's
|
|
130
|
-
just an easy way to avoid browsers or backends messing with special characters.
|
|
131
|
-
|
|
132
|
-
But as a trivial example, if you call `Identity.login(..)` with params
|
|
133
|
-
`redirectUri=https://site.com&state=article%3D1234` — then at the end of the authentication flow,
|
|
134
|
-
the user will be sent back to your redirectUri, and the `state` parameter will be forwarded along
|
|
135
|
-
with the auth `code` parameter.
|
|
136
|
-
|
|
137
|
-
It is recommended that you provide a unique identifier as part of the state, to prevent CSRF
|
|
138
|
-
attacks. For example this can be accomplished by:
|
|
139
|
-
|
|
140
|
-
1. Your backend generates random token: `1234abcd`, saves it in some tokenCache, and forwards to
|
|
141
|
-
your browser frontend
|
|
142
|
-
1. Your frontend calls `Identity.login` with `state = base64Urlencode({ token: '1234abcd', article:
|
|
143
|
-
'1234', ... })`
|
|
144
|
-
1. When auth flow completes, the user is redirected back to your site. Then, your backend sees the
|
|
145
|
-
query parameters `code` (which it can exchange for OAuth tokens for the user) and `state`
|
|
146
|
-
1. Your backend can do `decodedState = base64Urldecode(query.state)` and then verify that its
|
|
147
|
-
`tokenCache.contains(decodedState.token)`. If that fails, then possibly a CSRF attack was
|
|
148
|
-
attempted. If successful, remove the token from the tokenCache so the same token can't be used
|
|
149
|
-
again, and continue to show `decodedState.article`
|
|
150
|
-
|
|
151
|
-
#### Authentication methods
|
|
152
|
-
|
|
153
|
-
Although Schibsted account abstracts away the details of how the users sign up or log in, it's worth
|
|
154
|
-
mentioning that your end users have a few ways to log in:
|
|
44
|
+
## API Documentation
|
|
155
45
|
|
|
156
|
-
|
|
157
|
-
self-chosen password
|
|
158
|
-
* Passwordless - email: here, the users enter their email address and receive a one-time code that
|
|
159
|
-
they can use to log in
|
|
160
|
-
* Multifactor authentication: first client indicates which methods should be preferred, later these
|
|
161
|
-
will be included (if fulfilled) in `AMR` claim of IDToken
|
|
46
|
+
Public API documentation is generated from TypeScript source comments with TypeDoc.
|
|
162
47
|
|
|
163
|
-
|
|
164
|
-
`login()` function takes an optional parameter called `acrValues` (Authentication Context Class Reference).
|
|
165
|
-
The `acrValues` parameter with multifactor authentication can take following values:
|
|
48
|
+
Documentation commands:
|
|
166
49
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
* `sms` - authentication using SMS code sent to phone number
|
|
172
|
-
* `password otp sms` - those authentication methods might be combined
|
|
50
|
+
- `npm run docs:build` generates the documentation once in `docs/`.
|
|
51
|
+
- `npm run docs:watch` rebuilds `docs/` when source files change, without starting a server.
|
|
52
|
+
- `npm run docs:preview` builds and serves the documentation locally in the versioned layout.
|
|
53
|
+
- `npm run docs:test` tests documentation versioning and publishing.
|
|
173
54
|
|
|
174
|
-
|
|
175
|
-
domain, let the user authenticate there, and then have us redirect them back to your site. If you
|
|
176
|
-
prefer, we also provide a popup that you can use. In this method, the authentication happens on a
|
|
177
|
-
separate popup window and at the end of the auth flow. We recommend that you make the popup send a
|
|
178
|
-
signal to your main page — using
|
|
179
|
-
[postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) or something
|
|
180
|
-
similar — to indicate that the user is logged in. If the popup window fails to open, it'll
|
|
181
|
-
automatically fall back to the redirect flow. The SDK Example project mentioned above demonstrates
|
|
182
|
-
how it can work. Again, you can see [sdk-example](https://schibsted.ghe.com/user-identity/sdk-example) if you
|
|
183
|
-
want a working example.
|
|
55
|
+
Generated docs are written to `docs/` and are not committed.
|
|
184
56
|
|
|
185
|
-
|
|
57
|
+
After npm publishing succeeds, the
|
|
58
|
+
[documentation workflow](./.github/workflows/github-pages.yml) builds docs from the release tag and
|
|
59
|
+
adds them to the public
|
|
60
|
+
[`schibsted/account-sdk-browser`](https://github.com/schibsted/account-sdk-browser) repository.
|
|
61
|
+
Existing versions remain available, and the documentation root and version selector point to the
|
|
62
|
+
latest published version.
|
|
186
63
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
64
|
+
To publish an existing release again, run the documentation workflow manually with its tag.
|
|
65
|
+
Publishing requires the `public-docs` environment with a `PUBLIC_GITHUB_DOCS_DEPLOY_KEY` secret
|
|
66
|
+
containing the private key for a write-enabled deploy key configured in the public repository.
|
|
190
67
|
|
|
191
|
-
|
|
192
|
-
tells you if the user that is visiting your site is already logged in to Schibsted account or not.
|
|
68
|
+
## Example Project
|
|
193
69
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
same time `isConnected=false` if they have logged in to Schibsted account, but not accepted terms
|
|
197
|
-
and privacy policy for your site.
|
|
198
|
-
|
|
199
|
-
If you've lately changed your terms & conditions, maybe the user still hasn't accepted them. In that
|
|
200
|
-
case they are considered *not connected*. In that case, if they click "Log in" from your site, we
|
|
201
|
-
will just ask them to accept those terms and redirect them right back to your site.
|
|
202
|
-
|
|
203
|
-
#### Logging out
|
|
204
|
-
|
|
205
|
-
If you want to log the user out of Schibsted account, you can call
|
|
206
|
-
[Identity#logout](https://schibsted.github.io/account-sdk-browser/Identity.html#logout). This
|
|
207
|
-
will remove the Schibsted account brand session. User will still be logged into Schibsted account.
|
|
208
|
-
|
|
209
|
-
## Monetization
|
|
210
|
-
|
|
211
|
-
The preferred method for checking whether a user has access to a product/subscription is
|
|
212
|
-
[Monetization#hasAccess](https://schibsted.github.io/account-sdk-browser/Monetization.html#hasAccess).
|
|
213
|
-
It requires using Session Service, and supports both Schibsted account productId's and Zuora
|
|
214
|
-
feature id's.
|
|
215
|
-
|
|
216
|
-
#### Example
|
|
217
|
-
|
|
218
|
-
```javascript
|
|
219
|
-
import { Monetization } from '@schibsted/account-sdk-browser';
|
|
220
|
-
|
|
221
|
-
const monetization = new Monetization({
|
|
222
|
-
clientId: '56e9a5d1eee0000000000000',
|
|
223
|
-
redirectUri: 'https://awesomenews.site', // ensure it's listed in selfservice
|
|
224
|
-
sessionDomain: 'https://id.aweseome.site', // client-configured session-service domain
|
|
225
|
-
env: 'PRE', // Schibsted account env. A url or a special key: 'PRE', 'PRO' or 'PRO_NO'
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
// Check if the user has access to a a particular product
|
|
230
|
-
const userId = await identity.getUserId();
|
|
231
|
-
const data = await monetization.hasAccess([productId], userId);
|
|
232
|
-
alert(`User has access to ${productId}? ${data.entitled}`);
|
|
233
|
-
} catch (err) {
|
|
234
|
-
alert(`Could not query if the user has access to ${productId} because ${err}`);
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
## Payment
|
|
239
|
-
|
|
240
|
-
This class provides methods for paying with a so-called paylink, buying a product, getting links to
|
|
241
|
-
pages for redeeming voucher codes, reviewing payment history, and more.
|
|
242
|
-
|
|
243
|
-
#### Example
|
|
244
|
-
|
|
245
|
-
```javascript
|
|
246
|
-
import { Payment } from '@schibsted/account-sdk-browser';
|
|
247
|
-
|
|
248
|
-
const paymentSDK = new Payment({
|
|
249
|
-
clientId: '56e9a5d1eee0000000000000',
|
|
250
|
-
redirectUri: 'https://awesomenews.site', // ensure it's listed in selfservice
|
|
251
|
-
env: 'PRE', // Schibsted account env. A url or a special key: 'PRE', 'PRO' or 'PRO_NO'
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
// Get the url to paymentSDK with paylink
|
|
255
|
-
const paylink = '...';
|
|
256
|
-
const paylinkUrl = paymentSDK.purchasePaylinkUrl(paylink);
|
|
257
|
-
|
|
258
|
-
// Or another example --- pay with paylink in a popup
|
|
259
|
-
paymentSDK.payWithPaylink(paylink);
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
#### Cookies
|
|
263
|
-
|
|
264
|
-
There are some cookies used by Schibsted account. They should all be considered opaque on the
|
|
265
|
-
browser side. Nevertheless, here is a short description of them.
|
|
266
|
-
|
|
267
|
-
1. The **autologin** cookie (often called 'the remember-me-cookie'): The cookie name in the
|
|
268
|
-
production environments is `vgs_email`, because reasons (on PRE, it is called `spid-pre-data`).
|
|
269
|
-
It's a JSON string that's encoded using the standard `encodeURIComponent()` function and is an
|
|
270
|
-
object that contains two pieces of information that's important:
|
|
271
|
-
* `remember`: if set to `true`, the user chose to be remembered and this means we usually support
|
|
272
|
-
auto-login (that is, if you call the Schibsted account hassession service, and no session can
|
|
273
|
-
be found in the session database, it will automatically create a new one for the user so that
|
|
274
|
-
they don't have to authenticate again. If it is `false`, it should be interpreted as the user
|
|
275
|
-
does not want to be automatically logged in to any site when their session expires
|
|
276
|
-
* `v`: the version number
|
|
277
|
-
1. The **session** cookies: Cookie names in production environments are `identity`, and `SPID_SE` or
|
|
278
|
-
`SPID_NO`. It contains:
|
|
279
|
-
* `user`: an object (if it's missing, a call to hassession will return a `401` with a
|
|
280
|
-
`UserException` that says `No session found`)
|
|
281
|
-
* `userId` identifies the user. We use this property to compare "old" user with "new" user and
|
|
282
|
-
fire events that indicate that the user has changed
|
|
283
|
-
* `is_logged_in` indicates if the user is logged in
|
|
284
|
-
* `user_tags`: a map that contains some flags about the user; namely:
|
|
285
|
-
* `is_logged_in` indicates if the user is logged in (this seems to be a duplicate of a
|
|
286
|
-
property with a similar name in the parent `user` object)
|
|
287
|
-
* `terms`: a map of term ids that indicate if they've been accepted by the user.
|
|
288
|
-
* `referer` (yep, missing the double "rr"..): If this is missing, a call to hassession will
|
|
289
|
-
return a `401` with a `UserException` that says `No session found`.
|
|
70
|
+
The internal example integration is available in the
|
|
71
|
+
[sdk-example repository](https://schibsted.ghe.com/user-identity/sdk-example).
|
|
290
72
|
|
|
291
73
|
## Publishing
|
|
292
74
|
|
|
293
|
-
Versioning and changelog are handled by
|
|
75
|
+
Versioning and changelog updates are handled by
|
|
76
|
+
[Release Please](https://github.com/googleapis/release-please). The release configuration lives in
|
|
77
|
+
[`release-please-config.json`](./release-please-config.json), and publishing to
|
|
78
|
+
[npmjs.org](https://www.npmjs.com/package/@schibsted/account-sdk-browser) is handled by the
|
|
79
|
+
[npm-publish workflow](./.github/workflows/npm-publish.yml) when a GitHub Release is published.
|
|
294
80
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
Other prefixes (`chore:`, `docs:`, `test:`, `refactor:`, `ci:`, `build:`, `style:`) do not trigger a release and are hidden from the changelog.
|
|
81
|
+
Use [Conventional Commits](https://www.conventionalcommits.org/) for changes that should be picked
|
|
82
|
+
up by release automation.
|
|
298
83
|
|
|
299
|
-
|
|
300
|
-
Release-please will create a git tag (e.g. `v5.2.7`) and a GitHub Release, and the [publish workflow](./.github/workflows/npm-publish.yml) will push the package to npmjs.org.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
## LICENSE
|
|
84
|
+
## License
|
|
304
85
|
|
|
305
86
|
Copyright (c) 2026 Schibsted Products & Technology AS
|
|
306
87
|
|
|
307
|
-
Licensed under the [MIT
|
|
308
|
-
License](https://schibsted.ghe.com/user-identity/account-sdk-browser/blob/master/LICENSE.md)
|
|
309
|
-
|
|
310
|
-
Unless required by applicable law or agreed to in writing, software distributed under the License is
|
|
311
|
-
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
312
|
-
implied. See the License for the specific language governing permissions and limitations under the
|
|
313
|
-
License.
|
|
88
|
+
Licensed under the [MIT License](./LICENSE.md).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Account } from './account.js';
|
|
2
|
+
import { AccountConfig } from './types/account.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates and registers the single Account SDK instance for the current browser window.
|
|
5
|
+
*
|
|
6
|
+
* The created instance is stored on `window.schAccount` and the SDK emits
|
|
7
|
+
* `schAccount:ready` with the instance in `event.detail.instance`.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Client, redirect, environment, and Session Service configuration.
|
|
10
|
+
* @throws {SDKError} If the SDK cannot run in the current browser context, if an Account instance
|
|
11
|
+
* has already been initialized, or if configuration validation fails.
|
|
12
|
+
* @group Core API
|
|
13
|
+
*/
|
|
14
|
+
export declare function createAccountSdk(config: AccountConfig): Account;
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the Account SDK instance registered by `createAccountSdk()`.
|
|
17
|
+
*
|
|
18
|
+
* If the instance already exists, the promise resolves immediately. Otherwise it waits for
|
|
19
|
+
* `schAccount:ready` and rejects if initialization does not happen within the SDK timeout.
|
|
20
|
+
* @group Core API
|
|
21
|
+
*/
|
|
22
|
+
export declare function getAccountSdk(): Promise<Account>;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { AccountConfig, AccountEventListener, AccountEventName } from './types/account.js';
|
|
2
|
+
import { LoginOptions, SimplifiedLoginData, SimplifiedLoginWidgetLoginOptions, SimplifiedLoginWidgetOptions } from './types/login.js';
|
|
3
|
+
import { HasAccessResult } from './types/monetization.js';
|
|
4
|
+
import { ConnectedSessionResponse, SessionResponse, SessionUserId } from './types/session.js';
|
|
5
|
+
/**
|
|
6
|
+
* Unified client-side interface for a configured Schibsted Account integration.
|
|
7
|
+
*
|
|
8
|
+
* Create an instance with `createAccountSdk()` unless you explicitly need to construct it
|
|
9
|
+
* yourself. The instance coordinates identity, login, session, and access-check features for one
|
|
10
|
+
* configured client.
|
|
11
|
+
*
|
|
12
|
+
* @group Core API
|
|
13
|
+
*/
|
|
14
|
+
export declare class Account {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(config: AccountConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Queries Session Service and returns the current browser session state.
|
|
19
|
+
*
|
|
20
|
+
* This call may trigger a full-page session refresh redirect. Configure
|
|
21
|
+
* `callbackBeforeRedirect` if your app needs to persist state before that navigation.
|
|
22
|
+
*
|
|
23
|
+
* @throws {SDKError} If the Session Service call fails.
|
|
24
|
+
*/
|
|
25
|
+
hasSession(): Promise<SessionResponse>;
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether the browser currently has a Schibsted Account session.
|
|
28
|
+
*
|
|
29
|
+
* Returns `false` instead of throwing when the session lookup fails.
|
|
30
|
+
*/
|
|
31
|
+
isLoggedIn(): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Checks whether the current user is connected to the configured client.
|
|
34
|
+
*
|
|
35
|
+
* A user can be logged in to Schibsted Account without being connected to your client, for
|
|
36
|
+
* example before accepting required terms.
|
|
37
|
+
*/
|
|
38
|
+
isConnected(): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Returns the connected user session data.
|
|
41
|
+
*
|
|
42
|
+
* @throws {SDKError} If the user is not connected to the configured client.
|
|
43
|
+
*/
|
|
44
|
+
getUser(): Promise<ConnectedSessionResponse>;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the realm-specific Schibsted Account user id as a number.
|
|
47
|
+
*
|
|
48
|
+
* Use `getUserUuid()` when you need the globally unique user id.
|
|
49
|
+
*
|
|
50
|
+
* @throws {SDKError} If the user is not connected to the configured client.
|
|
51
|
+
*/
|
|
52
|
+
getUserId(): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* Returns an external identifier for the authenticated user, scoped to the configured client
|
|
55
|
+
* and external party.
|
|
56
|
+
*
|
|
57
|
+
* @param externalParty - External party for which the identifier is generated.
|
|
58
|
+
* @param optionalSuffix - Optional suffix included when generating the identifier.
|
|
59
|
+
* @throws {SDKError} If the session lookup fails, the session does not contain a `pairId`, or
|
|
60
|
+
* `externalParty` is empty.
|
|
61
|
+
* @deprecated Retained for compatibility with existing integrations. Avoid new usage.
|
|
62
|
+
*/
|
|
63
|
+
getExternalId(externalParty: string, optionalSuffix?: string): Promise<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Returns the globally unique user id from the current session.
|
|
66
|
+
*
|
|
67
|
+
* @throws {SDKError} If the user is not connected to the configured client.
|
|
68
|
+
*/
|
|
69
|
+
getUserUuid(): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Returns the user SDRN from the current session.
|
|
72
|
+
*
|
|
73
|
+
* @throws {SDKError} If the SDRN is missing from the session response.
|
|
74
|
+
*/
|
|
75
|
+
getUserSDRN(): Promise<string>;
|
|
76
|
+
/**
|
|
77
|
+
* Returns minimal user context for simplified login prompts.
|
|
78
|
+
*
|
|
79
|
+
* Returns `null` if the global account session cannot be read.
|
|
80
|
+
*/
|
|
81
|
+
getUserContextData(): Promise<SimplifiedLoginData | null>;
|
|
82
|
+
/**
|
|
83
|
+
* Returns the Varnish `sp_id` value from the current session when present.
|
|
84
|
+
*/
|
|
85
|
+
getSpId(): Promise<string | null>;
|
|
86
|
+
/**
|
|
87
|
+
* Starts the login flow with either a full-page redirect or a popup.
|
|
88
|
+
*
|
|
89
|
+
* Call this from a user gesture when `preferPopup` is enabled, otherwise browser popup blockers
|
|
90
|
+
* may block the popup and the SDK will fall back to redirect navigation.
|
|
91
|
+
*
|
|
92
|
+
* @param options - Login URL parameters.
|
|
93
|
+
* @returns A popup window reference when a popup is opened; otherwise `null`.
|
|
94
|
+
*/
|
|
95
|
+
login(options: LoginOptions): Window | null;
|
|
96
|
+
/**
|
|
97
|
+
* Logs the user out from the brand Session Service session and redirects the browser.
|
|
98
|
+
*
|
|
99
|
+
* @param redirectUri - Where Session Service should redirect the browser after logout.
|
|
100
|
+
*/
|
|
101
|
+
logout(redirectUri?: string): void;
|
|
102
|
+
/**
|
|
103
|
+
* Builds the login URL without navigating the browser.
|
|
104
|
+
*
|
|
105
|
+
* @param options - Login URL parameters.
|
|
106
|
+
*/
|
|
107
|
+
loginUrl(options: LoginOptions): string;
|
|
108
|
+
/**
|
|
109
|
+
* Builds the logout URL without navigating the browser.
|
|
110
|
+
*
|
|
111
|
+
* @param redirectUri - Where Session Service should redirect the browser after logout.
|
|
112
|
+
*/
|
|
113
|
+
logoutUrl(redirectUri?: string): string;
|
|
114
|
+
/**
|
|
115
|
+
* Builds the Schibsted Account profile page URL.
|
|
116
|
+
*
|
|
117
|
+
* @param redirectUri - Where the account page should redirect the browser afterwards.
|
|
118
|
+
*/
|
|
119
|
+
accountUrl(redirectUri?: string): string;
|
|
120
|
+
/**
|
|
121
|
+
* Loads and displays the simplified login widget when user context is available.
|
|
122
|
+
*
|
|
123
|
+
* Your application decides how often to call this method. The `state` field in `loginParams`
|
|
124
|
+
* may be a string or a function that resolves to a string.
|
|
125
|
+
* Widget open and cancel events can be observed with `on()`.
|
|
126
|
+
*
|
|
127
|
+
* @returns `true` when the widget was displayed.
|
|
128
|
+
* @throws {SDKError} If user context data is missing or the widget script cannot be loaded.
|
|
129
|
+
*/
|
|
130
|
+
showSimplifiedLoginWidget(loginParams: SimplifiedLoginWidgetLoginOptions, options?: SimplifiedLoginWidgetOptions): Promise<boolean>;
|
|
131
|
+
/**
|
|
132
|
+
* Enables or disables caching for subsequent session lookups.
|
|
133
|
+
*
|
|
134
|
+
* Changing this setting does not remove an existing cached session.
|
|
135
|
+
*/
|
|
136
|
+
setSessionCachingEnabled(enabled: boolean): void;
|
|
137
|
+
/**
|
|
138
|
+
* Removes the cached Session Service user session response.
|
|
139
|
+
*/
|
|
140
|
+
clearCachedUserSession(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Checks whether the current user has access to any of the requested products or features.
|
|
143
|
+
*
|
|
144
|
+
* When `productIds` is omitted, the ids configured as `defaultProductIds` are used.
|
|
145
|
+
* Results are cached according to the TTL returned by Session Service.
|
|
146
|
+
*
|
|
147
|
+
* @param productIds - Product or feature ids to check instead of the configured defaults.
|
|
148
|
+
* @returns Access data, or `null` when the user is not entitled.
|
|
149
|
+
* @throws {SDKError} If product ids are not provided or configured, `sessionDomain` is missing,
|
|
150
|
+
* the current user cannot be resolved, input is invalid, or the request fails.
|
|
151
|
+
*/
|
|
152
|
+
hasAccess(productIds?: string[] | undefined): Promise<HasAccessResult | null>;
|
|
153
|
+
/**
|
|
154
|
+
* Removes a cached access-check result.
|
|
155
|
+
*
|
|
156
|
+
* @param productIds - Product or feature ids used for the cached lookup.
|
|
157
|
+
* @param userId - User id used for the cached lookup.
|
|
158
|
+
*/
|
|
159
|
+
clearCachedAccessResult(productIds: string[], userId: SessionUserId): void;
|
|
160
|
+
/**
|
|
161
|
+
* Subscribes to Account events.
|
|
162
|
+
*
|
|
163
|
+
* Supported event names are defined by {@link AccountEventName}.
|
|
164
|
+
*
|
|
165
|
+
* @param event - Event name.
|
|
166
|
+
* @param listener - Listener that receives an `Event` or `CustomEvent`.
|
|
167
|
+
*/
|
|
168
|
+
on<EventName extends AccountEventName>(event: EventName, listener: AccountEventListener<EventName>): this;
|
|
169
|
+
/**
|
|
170
|
+
* Unsubscribes from Account events.
|
|
171
|
+
*
|
|
172
|
+
* Supported event names are defined by {@link AccountEventName}.
|
|
173
|
+
*
|
|
174
|
+
* @param event - Event name.
|
|
175
|
+
* @param listener - Listener to remove.
|
|
176
|
+
*/
|
|
177
|
+
off<EventName extends AccountEventName>(event: EventName, listener: AccountEventListener<EventName>): this;
|
|
178
|
+
}
|
|
179
|
+
export default Account;
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache implementation used when web storage is available. Wraps a `Storage` instance.
|
|
3
|
+
* @private
|
|
4
|
+
*/
|
|
5
|
+
declare class WebStorageCache {
|
|
6
|
+
store: Storage;
|
|
7
|
+
get: (key: string) => string | null;
|
|
8
|
+
set: (key: string, value: string) => void;
|
|
9
|
+
delete: (key: string) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Create web storage cache object
|
|
12
|
+
* @param store - A reference to either `sessionStorage` or `localStorage` from a
|
|
13
|
+
* `Window` object
|
|
14
|
+
*/
|
|
15
|
+
constructor(store: Storage);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Cache implementation used when web storage is not available. Stores entries in an in-memory object.
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
declare class LiteralCache {
|
|
22
|
+
store: Record<string, string>;
|
|
23
|
+
get: (key: string) => string | undefined;
|
|
24
|
+
set: (key: string, value: string) => void;
|
|
25
|
+
delete: (key: string) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Create JS object literal cache object
|
|
28
|
+
*/
|
|
29
|
+
constructor();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Cache class that attempts WebStorage (session/local storage), and falls back to JS object literal
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
export default class Cache {
|
|
36
|
+
cache: WebStorageCache | LiteralCache;
|
|
37
|
+
type: string;
|
|
38
|
+
/**
|
|
39
|
+
* @param storeProvider - A function to return a WebStorage instance (either
|
|
40
|
+
* `sessionStorage` or `localStorage` from a `Window` object)
|
|
41
|
+
* @throws {SDKError} - If sessionStorage or localStorage are not accessible
|
|
42
|
+
*/
|
|
43
|
+
constructor(storeProvider?: () => Storage);
|
|
44
|
+
/**
|
|
45
|
+
* Get a value from cache (checks that the object has not expired)
|
|
46
|
+
* @param key
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
get(key: string): unknown;
|
|
50
|
+
/**
|
|
51
|
+
* Set a cache entry
|
|
52
|
+
* @param key
|
|
53
|
+
* @param value
|
|
54
|
+
* @param expiresIn - Value in milliseconds until the entry expires
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
set(key: string, value: unknown, expiresIn?: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Delete a cache entry
|
|
60
|
+
* @param key
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
delete(key: string): void;
|
|
64
|
+
}
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LegacyCompatibilityOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Enables the temporary v5 global and ready-event compatibility layer for Account SDK v6.
|
|
4
|
+
*
|
|
5
|
+
* Call this before `createAccountSdk()` when a dependency still expects v5 globals. If Account
|
|
6
|
+
* already exists, the legacy shims are installed immediately.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Migrate dependencies to the Account API. This entrypoint will be removed in v7.
|
|
9
|
+
*/
|
|
10
|
+
export declare function enableLegacyCompatibility(options: LegacyCompatibilityOptions): void;
|