@sesamy/sesamy-js 1.119.1 → 1.120.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 +784 -197
- package/dist/bootstrap.d.ts +6 -1
- package/dist/bootstrap.iife.js +1 -1
- package/dist/bootstrap.mjs +23 -19
- package/dist/sesamy-js.cjs +3 -3
- package/dist/sesamy-js.d.ts +11 -0
- package/dist/sesamy-js.iife.js +3 -3
- package/dist/sesamy-js.mjs +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,22 +1,533 @@
|
|
|
1
1
|
# sesamy-js
|
|
2
2
|
|
|
3
|
-
The Sesamy browser
|
|
3
|
+
The Sesamy browser JavaScript API.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@sesamy/sesamy-js` is the publisher-side runtime that powers paywalls,
|
|
6
|
+
authentication, content gating, and analytics on Sesamy-integrated sites. It
|
|
7
|
+
exposes a single `window.sesamy` object (the namespace is configurable) with
|
|
8
|
+
~30 namespaced services backed by the Sesamy API, plus ready-made handlers for
|
|
9
|
+
URL/hash triggers, content selectors, DOM transforms, consent, and DCA
|
|
10
|
+
(Capsule) decryption.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
# Installation
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
```bash
|
|
15
|
+
npm install @sesamy/sesamy-js
|
|
16
|
+
# or
|
|
17
|
+
pnpm add @sesamy/sesamy-js
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The package ships several entry points so you can pick the build that fits
|
|
21
|
+
your integration:
|
|
22
|
+
|
|
23
|
+
| Import | Purpose |
|
|
24
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
25
|
+
| `@sesamy/sesamy-js` | Core library — `init()` and the `SesamyAPI` surface (ESM/CJS). |
|
|
26
|
+
| `@sesamy/sesamy-js/auth0-plugin` | Auth0 SPA auth plugin. Required for SPA login unless using BFF cookies. |
|
|
27
|
+
| `@sesamy/sesamy-js/capsule-plugin` | Capsule (DCA) decryption plugin. Required when `capsule.enabled` is `true`. |
|
|
28
|
+
| `@sesamy/sesamy-js/bootstrap` | Tiny inline loader (`sesamyBootstrap` + `renderBootstrapScript`) that orchestrates the script chain and prefetches `/auth/userinfo`. |
|
|
29
|
+
|
|
30
|
+
Pre-built IIFE bundles for classic `<script>` tags are also published:
|
|
31
|
+
|
|
32
|
+
- `dist/sesamy-js.iife.js` — core, all-in-one (loadable directly without ESM).
|
|
33
|
+
- `dist/auth0-plugin.iife.js` — auth plugin as an IIFE that registers
|
|
34
|
+
`window.auth0Plugin.createAuth0Plugin`.
|
|
35
|
+
- `dist/capsule-plugin.iife.js` — capsule plugin as an IIFE that registers
|
|
36
|
+
`window.capsulePlugin.createCapsulePlugin`.
|
|
37
|
+
- `dist/bootstrap.iife.js` — bootstrap loader as an IIFE.
|
|
38
|
+
|
|
39
|
+
Publishers using Sesamy's hosted scripts host typically don't reference these
|
|
40
|
+
files directly; instead they let the bootstrap loader resolve them from
|
|
41
|
+
`https://scripts.sesamy.com/s/{clientId}/{name}/{version}.js`.
|
|
42
|
+
|
|
43
|
+
# Quick start
|
|
44
|
+
|
|
45
|
+
The recommended way to embed sesamy-js on a publisher site is via the
|
|
46
|
+
**bootstrap loader**. It downloads the auth/capsule plugins, the components
|
|
47
|
+
package, and the core bundle in parallel (in the right execution order) and
|
|
48
|
+
prefetches `/auth/userinfo` so the user's session is hydrated by the time the
|
|
49
|
+
core finishes loading.
|
|
50
|
+
|
|
51
|
+
Drop this in `<head>`:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<script type="application/json" id="sesamy-js">
|
|
55
|
+
{
|
|
56
|
+
"clientId": "your-client-id",
|
|
57
|
+
"environment": "prod"
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
60
|
+
<script src="https://scripts.sesamy.com/s/your-client-id/bootstrap/stable.js"></script>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The bootstrap script auto-detects the `<script id="sesamy-js">` config element
|
|
64
|
+
and pulls forward `clientId`, `environment`, `version`, `src`, plugin-version
|
|
65
|
+
overrides, fallback options, and the plugin/component flags below. No extra
|
|
66
|
+
inline call is needed.
|
|
67
|
+
|
|
68
|
+
Once the chain finishes, sesamy-js is reachable as `window.sesamy` (or the
|
|
69
|
+
namespace you set in `api.namespace`) and the `sesamyJsReady` event fires.
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
window.addEventListener('sesamyJsReady', () => {
|
|
73
|
+
console.log('Authenticated?', window.sesamy.auth.isAuthenticated());
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
# Integration modes
|
|
78
|
+
|
|
79
|
+
sesamy-js supports several distinct integration shapes. Pick the one that
|
|
80
|
+
matches your stack — they are not mutually exclusive (e.g. you can use the
|
|
81
|
+
bootstrap loader together with BFF cookie auth).
|
|
82
|
+
|
|
83
|
+
## Bootstrap loader (recommended)
|
|
84
|
+
|
|
85
|
+
Use when: you embed sesamy-js on a server-rendered publisher site and want a
|
|
86
|
+
single `<script>` in `<head>` that handles everything. Sets
|
|
87
|
+
`window.__sesamyBoot` with a parallel userinfo prefetch promise that the core
|
|
88
|
+
reuses, eliminating a round-trip from the critical path.
|
|
89
|
+
|
|
90
|
+
The bootstrap loader (`@sesamy/sesamy-js/bootstrap`) ships a
|
|
91
|
+
`sesamyBootstrap(options)` function that:
|
|
92
|
+
|
|
93
|
+
1. Optionally fetches `/auth/userinfo` in parallel with the bundle download
|
|
94
|
+
when the `sesamy_is_authenticated=true` hint cookie is present (or skips
|
|
95
|
+
if `skipAuthPrefetch` is `true`).
|
|
96
|
+
2. Injects the auth0-plugin, capsule-plugin (if enabled), sesamy-components,
|
|
97
|
+
and the sesamy-js core as `<script async=false>` tags so they execute in
|
|
98
|
+
order while downloading in parallel.
|
|
99
|
+
3. Falls back to `fallbackSrc` if the primary core never installs
|
|
100
|
+
`window[namespace]` within `fallbackTimeoutMs` (default 3000ms).
|
|
101
|
+
|
|
102
|
+
Auto-run from the config element:
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<script type="application/json" id="sesamy-js">
|
|
106
|
+
{ "clientId": "demo", "environment": "prod" }
|
|
107
|
+
</script>
|
|
108
|
+
<script src="https://scripts.sesamy.com/s/demo/bootstrap/stable.js"></script>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or call it manually (useful from SSR templates, before the config element is
|
|
112
|
+
in the DOM):
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<script>
|
|
116
|
+
sesamyBootstrap({
|
|
117
|
+
clientId: 'demo',
|
|
118
|
+
environment: 'prod',
|
|
119
|
+
version: 'stable',
|
|
120
|
+
fallbackSrc: 'https://scripts-fallback.sesamy.com/.../sesamy-js.iife.js',
|
|
121
|
+
debug: false,
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For server-rendered pages, use `renderBootstrapScript()` to serialise the
|
|
127
|
+
function plus its options into an inline script body:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { renderBootstrapScript } from '@sesamy/sesamy-js/bootstrap';
|
|
131
|
+
|
|
132
|
+
const inline = renderBootstrapScript({
|
|
133
|
+
clientId: 'demo',
|
|
134
|
+
environment: 'prod',
|
|
135
|
+
skipAuthPrefetch: false,
|
|
136
|
+
});
|
|
137
|
+
// emit `<script>${inline}</script>` in your HTML response
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `BootstrapOptions`
|
|
141
|
+
|
|
142
|
+
| Option | Type | Default | Purpose |
|
|
143
|
+
| ---------------------- | ----------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
144
|
+
| `clientId` | `string` | — | Resolves script chain URLs to `https://scripts.sesamy.com/s/{clientId}/{name}/{version}.js`. Required unless `src` is set. |
|
|
145
|
+
| `version` | `string` | `'stable'` | Version channel served by scripts-host. |
|
|
146
|
+
| `componentsVersion` | `string` | `version` | Per-entry override for `sesamy-components`. |
|
|
147
|
+
| `auth0PluginVersion` | `string` | `version` | Per-entry override for `auth0-plugin`. |
|
|
148
|
+
| `capsulePluginVersion` | `string` | `version` | Per-entry override for `capsule-plugin`. |
|
|
149
|
+
| `src` | `string` | — | Override the core bundle URL. Disables plugin/component chaining (escape hatch for self-contained bundles). |
|
|
150
|
+
| `environment` | `'dev' \| 'prod'` | `'prod'` | Origin to resolve `clientId` against (`scripts.sesamy.com` vs `scripts.sesamy.dev`). |
|
|
151
|
+
| `fallbackSrc` | `string` | — | Secondary bundle URL loaded if the core fails or doesn't install `window[namespace]` in time. |
|
|
152
|
+
| `fallbackTimeoutMs` | `number` | `3000` | Timeout before the fallback fires. |
|
|
153
|
+
| `apiBaseUrl` | `string` | inferred | Base URL for the userinfo prefetch. When unset, falls back to `auth.baseUrl` from the page config (so the prefetch matches the runtime BFF plugin) and then to same-origin. |
|
|
154
|
+
| `namespace` | `string` | `'sesamy'` | Window namespace the core installs onto. |
|
|
155
|
+
| `skipAuthPrefetch` | `boolean` | `false` | Skip the `/auth/userinfo` prefetch (e.g. when injecting the id-token via SSR). |
|
|
156
|
+
| `skipComponents` | `boolean` | `false` | Skip loading `sesamy-components`. |
|
|
157
|
+
| `loadAuth0Plugin` | `boolean` | inferred | Force auth0-plugin loading on/off. Default: load unless `auth.useHttpCookies === true` in the config element. |
|
|
158
|
+
| `loadCapsulePlugin` | `boolean` | inferred | Force capsule-plugin loading on/off. Default: load when `capsule.enabled === true` in the config element. |
|
|
159
|
+
| `debug` | `boolean` | `false` | Emit `[sesamy-boot]` log lines for chain decisions, prefetch source, load/error events, and fallback triggers. |
|
|
160
|
+
|
|
161
|
+
## Auto-init from `<script id="sesamy-js">`
|
|
162
|
+
|
|
163
|
+
Use when: you've already loaded the core bundle some other way (custom CDN,
|
|
164
|
+
self-host) and just want sesamy-js to bootstrap itself from a JSON config
|
|
165
|
+
block.
|
|
166
|
+
|
|
167
|
+
The core looks for a `<script type="application/json" id="sesamy-js">` element
|
|
168
|
+
and, if found, calls `init()` with the parsed config. Only `clientId` is
|
|
169
|
+
required.
|
|
170
|
+
|
|
171
|
+
```html
|
|
172
|
+
<script type="application/json" id="sesamy-js">
|
|
173
|
+
{
|
|
174
|
+
"clientId": "demo",
|
|
175
|
+
"environment": "prod",
|
|
176
|
+
"auth": { "domain": "auth.example.com" },
|
|
177
|
+
"api": { "namespace": "sesamy" }
|
|
178
|
+
}
|
|
179
|
+
</script>
|
|
180
|
+
<script src="/path/to/sesamy-js.iife.js"></script>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Programmatic `init(config)`
|
|
184
|
+
|
|
185
|
+
Use when: your app is an SPA that already manages its own bootstrapping (e.g.
|
|
186
|
+
you import sesamy-js from npm and want full control over when it initialises).
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { init } from '@sesamy/sesamy-js';
|
|
190
|
+
|
|
191
|
+
const sesamy = await init({
|
|
192
|
+
clientId: 'demo',
|
|
193
|
+
vendorId: 'demo',
|
|
194
|
+
environment: 'prod',
|
|
195
|
+
auth: { domain: 'auth.example.com' },
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
if (await sesamy.auth.isAuthenticated()) {
|
|
199
|
+
const profile = await sesamy.profile.get();
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`init()` returns the `SesamyAPI` object and also installs it on
|
|
204
|
+
`window[namespace]` for parity with the auto-init path. Pass `awaitAllServices:
|
|
205
|
+
true` in the config to make the returned promise wait for analytics, auth,
|
|
206
|
+
content, transforms, and capsule to finish initialising; the default is to
|
|
207
|
+
return early and run those services in the background.
|
|
208
|
+
|
|
209
|
+
You can also pass plugins explicitly instead of relying on
|
|
210
|
+
`window.auth0Plugin` / `window.capsulePlugin` auto-detection:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { init } from '@sesamy/sesamy-js';
|
|
214
|
+
import { createAuth0Plugin } from '@sesamy/sesamy-js/auth0-plugin';
|
|
215
|
+
import { createCapsulePlugin } from '@sesamy/sesamy-js/capsule-plugin';
|
|
216
|
+
|
|
217
|
+
await init(config, {
|
|
218
|
+
authPlugin: createAuth0Plugin(),
|
|
219
|
+
capsulePlugin: createCapsulePlugin(),
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## BFF / cookie-based authentication
|
|
224
|
+
|
|
225
|
+
Use when: your backend already terminates Sesamy auth (the API proxy's Token
|
|
226
|
+
Handler) and you want sesamy-js to use HttpOnly cookies instead of the SPA
|
|
227
|
+
Auth0 plugin. The auth0-plugin is **not** loaded; login/logout/refresh go
|
|
228
|
+
through `/auth/login`, `/auth/callback`, `/auth/logout`, and `/auth/userinfo`
|
|
229
|
+
on the same origin by default.
|
|
230
|
+
|
|
231
|
+
```html
|
|
232
|
+
<script type="application/json" id="sesamy-js">
|
|
233
|
+
{
|
|
234
|
+
"clientId": "demo",
|
|
235
|
+
"vendorId": "demo",
|
|
236
|
+
"auth": { "useHttpCookies": true },
|
|
237
|
+
"api": { "endpoint": "" }
|
|
238
|
+
}
|
|
239
|
+
</script>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
To namespace auth under a sub-path (e.g. when running behind a first-party
|
|
243
|
+
proxy that reserves the top-level `/auth/*` path for something else), set
|
|
244
|
+
`auth.baseUrl`:
|
|
245
|
+
|
|
246
|
+
```html
|
|
247
|
+
<script type="application/json" id="sesamy-js">
|
|
248
|
+
{
|
|
249
|
+
"clientId": "acme",
|
|
250
|
+
"auth": { "useHttpCookies": true, "baseUrl": "/sesamy" }
|
|
251
|
+
}
|
|
252
|
+
</script>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The plugin then calls `/sesamy/auth/userinfo`, `/sesamy/auth/{vendor}/login`,
|
|
256
|
+
and `/sesamy/auth/logout`. `auth.baseUrl` is independent of `api.endpoint` —
|
|
257
|
+
the API and auth proxies may live on different sub-paths or hosts.
|
|
258
|
+
|
|
259
|
+
Notes:
|
|
260
|
+
|
|
261
|
+
- When `useHttpCookies` is `true` and no `api.endpoint` is set, sesamy-js
|
|
262
|
+
defaults the API endpoint to `/api` on the current origin (cross-origin
|
|
263
|
+
cookies can't reach `api2.sesamy.com`).
|
|
264
|
+
- For SSR, set `auth.idToken` to a server-injected id-token and sesamy-js
|
|
265
|
+
treats the user as authenticated immediately, skipping `/auth/userinfo`.
|
|
266
|
+
Alternatively include
|
|
267
|
+
`<script type="application/json" id="sesamy-server-state">{"idToken":"eyJ..."}</script>` —
|
|
268
|
+
the cookie-auth plugin reads it automatically.
|
|
269
|
+
- The bootstrap loader detects `useHttpCookies === true` in the config element
|
|
270
|
+
and skips the auth0-plugin entry in the chain.
|
|
271
|
+
|
|
272
|
+
## Capsule (DCA) decryption
|
|
273
|
+
|
|
274
|
+
Use when: your articles ship as encrypted DCA payloads and you need
|
|
275
|
+
sesamy-js to fetch unlock tokens, decrypt the manifest, and inject the
|
|
276
|
+
plaintext into `data-dca-content-name="..."` placeholders.
|
|
277
|
+
|
|
278
|
+
```html
|
|
279
|
+
<script type="application/json" id="sesamy-js">
|
|
280
|
+
{
|
|
281
|
+
"clientId": "demo",
|
|
282
|
+
"auth": { "useHttpCookies": true },
|
|
283
|
+
"capsule": { "enabled": true, "autoProcess": true }
|
|
284
|
+
}
|
|
285
|
+
</script>
|
|
286
|
+
|
|
287
|
+
<!-- Register the capsule plugin before sesamy-js auto-inits -->
|
|
288
|
+
<script type="module">
|
|
289
|
+
import { createCapsulePlugin } from '@sesamy/sesamy-js/capsule-plugin';
|
|
290
|
+
window.capsulePlugin = { createCapsulePlugin };
|
|
291
|
+
</script>
|
|
292
|
+
<script src="/path/to/sesamy-js.iife.js"></script>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
When `autoProcess` is `true` (the default), sesamy-js detects the DCA
|
|
296
|
+
manifest on page load, calls the unlock endpoint, decrypts every
|
|
297
|
+
`data-dca-content-name` block, and starts a `MutationObserver` for SPA
|
|
298
|
+
navigation. To process content manually call `sesamy.capsule.processPage()`,
|
|
299
|
+
or call `sesamy.content.unlock(selector)` for per-article control.
|
|
300
|
+
|
|
301
|
+
## IIFE / classic `<script>` tag
|
|
302
|
+
|
|
303
|
+
Use when: the host site has no build step. Drop the IIFE bundle in directly:
|
|
304
|
+
|
|
305
|
+
```html
|
|
306
|
+
<script type="application/json" id="sesamy-js">
|
|
307
|
+
{ "clientId": "demo" }
|
|
308
|
+
</script>
|
|
309
|
+
<script src="https://scripts.sesamy.com/s/demo/sesamy-js/stable.js"></script>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
The IIFE bundle assumes the auth0-plugin / capsule-plugin IIFEs (if needed)
|
|
313
|
+
have already executed and registered their factories on `window`. The
|
|
314
|
+
bootstrap loader automates that ordering — using IIFEs without the bootstrap
|
|
315
|
+
means you're responsible for inserting plugin scripts before the core script.
|
|
316
|
+
|
|
317
|
+
# Configuration
|
|
318
|
+
|
|
319
|
+
`init()` and the auto-init JSON block accept the same `Config` shape:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
interface Config {
|
|
323
|
+
clientId: string; // required
|
|
324
|
+
vendorId: string; // required
|
|
325
|
+
environment?: 'dev' | 'prod';
|
|
326
|
+
organization?: string; // Auth0 org id
|
|
327
|
+
api?: Partial<ApiConfig>;
|
|
328
|
+
analytics?: Partial<AnalyticsConfig>;
|
|
329
|
+
auth?: Partial<AuthConfig>;
|
|
330
|
+
content?: ContentNode[];
|
|
331
|
+
transform?: TransformConfig;
|
|
332
|
+
capsule?: CapsuleConfig;
|
|
333
|
+
consent?: ConsentConfig;
|
|
334
|
+
awaitAllServices?: boolean; // default: false
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## `api`
|
|
339
|
+
|
|
340
|
+
| Field | Type | Default | Purpose |
|
|
341
|
+
| ------------- | ----------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
342
|
+
| `namespace` | `string` | `'sesamy'` | Property on `window` where the API is installed. |
|
|
343
|
+
| `endpoint` | `string` | `https://api2.sesamy.com` | Absolute URL or relative path. Use a relative path (e.g. `/api`) when proxying through your own backend. |
|
|
344
|
+
| `environment` | `'dev' \| 'prod'` | inherits `Config.environment` | Picks `api2.sesamy.com` vs `api2.sesamy.dev`. |
|
|
345
|
+
|
|
346
|
+
When `auth.useHttpCookies` is `true` the API client switches to
|
|
347
|
+
`credentials: 'include'` and drops the `Authorization` header.
|
|
348
|
+
|
|
349
|
+
## `auth`
|
|
350
|
+
|
|
351
|
+
| Field | Type | Default | Purpose |
|
|
352
|
+
| ------------------ | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
353
|
+
| `enabled` | `boolean` | `true` | Disable auth entirely (anonymous-only mode). |
|
|
354
|
+
| `domain` | `string` | — | Single custom Auth0 domain. |
|
|
355
|
+
| `domains` | `string[]` | — | Multiple auth domains for multi-tenant / white-label setups. The library picks the entry whose top-level domain matches the current page; falls back to `domain`. |
|
|
356
|
+
| `useRefreshTokens` | `boolean` | `false` | Enable refresh-token rotation in the auth0-plugin. |
|
|
357
|
+
| `useHttpCookies` | `boolean` | `false` | Switch to cookie-based BFF auth. Skips the auth0-plugin even if registered. |
|
|
358
|
+
| `baseUrl` | `string` | `""` | Base URL the BFF plugin prepends to its `/auth/*` paths. Set when running behind a first-party proxy that namespaces auth under a sub-path (e.g. `"/sesamy"` → `/sesamy/auth/userinfo`, `/sesamy/auth/{vendor}/login`). Independent of `api.endpoint`. |
|
|
359
|
+
| `idToken` | `string` | — | Server-injected id-token for SSR. When set, sesamy-js treats the user as authenticated without calling `/auth/userinfo`. |
|
|
360
|
+
|
|
361
|
+
See [Cross-domain authentication](#cross-domain-authentication) below for how
|
|
362
|
+
the library picks between popup and redirect login on cross-domain setups.
|
|
363
|
+
|
|
364
|
+
## `analytics`
|
|
365
|
+
|
|
366
|
+
| Field | Type | Default | Purpose |
|
|
367
|
+
| ------------- | ----------------- | -------- | --------------------------------------------- |
|
|
368
|
+
| `enabled` | `boolean` | `true` | Toggle the analytics service. |
|
|
369
|
+
| `environment` | `'dev' \| 'prod'` | inherits | Picks `logs.sesamy.com` vs `logs.sesamy.dev`. |
|
|
370
|
+
|
|
371
|
+
The analytics service is built on [GetAnalytics](https://getanalytics.io/) and
|
|
372
|
+
ships these events to the Sesamy interaction endpoint:
|
|
373
|
+
|
|
374
|
+
- Page views, triggered on router updates.
|
|
375
|
+
- Scroll events at 25%, 50%, 75%, 100%.
|
|
376
|
+
- Active vs idle duration.
|
|
377
|
+
- Custom events emitted via `analytics.track(name, properties)`.
|
|
378
|
+
- All events emitted through `events.emit(...)` (prefixed with `event:`).
|
|
379
|
+
|
|
380
|
+
When `consent.enabled` is `true`, analytics storage is gated on the
|
|
381
|
+
`statistics` consent flag — see [Consent](#consent) below.
|
|
382
|
+
|
|
383
|
+
## `content`
|
|
384
|
+
|
|
385
|
+
An array of `ContentNode` objects describing how to discover articles in the
|
|
386
|
+
DOM and (optionally) what paywall rules apply. Each node currently has
|
|
387
|
+
`type: 'article'` and supports the following matchers and selectors:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
{
|
|
391
|
+
type: 'article',
|
|
392
|
+
// Matchers — all optional, AND-ed together
|
|
393
|
+
path?: string, // current URL contains this path
|
|
394
|
+
queryParam?: { key: string; value: string },
|
|
395
|
+
headers?: { name: string; contains: string },
|
|
396
|
+
userAgentContains?: string,
|
|
397
|
+
// Pricing / paywall metadata (forwarded to checkout)
|
|
398
|
+
pass?: string,
|
|
399
|
+
price?: { amount: number; currency: string },
|
|
400
|
+
paywallUrl?: string,
|
|
401
|
+
enablePaywallSettingsUrlFallback?: boolean,
|
|
402
|
+
// DOM selectors (defaults provided — override per site)
|
|
403
|
+
selectors?: {
|
|
404
|
+
article?: { selector: string; attribute?: string },
|
|
405
|
+
image?: { selector: string; attribute?: string },
|
|
406
|
+
title?: { selector: string; attribute?: string },
|
|
407
|
+
excerpt?: { selector: string; attribute?: string },
|
|
408
|
+
price?: { selector: string; attribute?: string },
|
|
409
|
+
currency?: { selector: string; attribute?: string },
|
|
410
|
+
accessLevel?: { selector: string; attribute?: string },
|
|
411
|
+
url?: { selector: string; attribute?: string },
|
|
412
|
+
pass?: { selector: string; attribute?: string },
|
|
413
|
+
id?: { selector: string; attribute?: string },
|
|
414
|
+
paywallUrl?: { selector: string; attribute?: string },
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
See the [Content](#content-1) section below for `content.list/get/hasAccess/unlock`
|
|
420
|
+
and the modal/notification-bar UI helpers.
|
|
421
|
+
|
|
422
|
+
## `transform`
|
|
423
|
+
|
|
424
|
+
Selector-based DOM rules applied after content discovery (and after Capsule
|
|
425
|
+
decryption when DCA is enabled).
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
{
|
|
429
|
+
enabled?: boolean,
|
|
430
|
+
rules: Array<{
|
|
431
|
+
selector: string,
|
|
432
|
+
transform: 'insert' | 'replace' | 'remove' | 'gradient' | 'wrap',
|
|
433
|
+
contentType: 'html' | 'selector' | 'url',
|
|
434
|
+
content?: string,
|
|
435
|
+
insertionPoint?: 'before' | 'after' | 'inside',
|
|
436
|
+
path?: string, // only apply on matching URLs
|
|
437
|
+
entitlement?: string, // only apply when user has this entitlement
|
|
438
|
+
authenticated?: boolean, // only apply for logged-in users
|
|
439
|
+
}>
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
See [Transforms](#transforms) below for full semantics and examples.
|
|
444
|
+
|
|
445
|
+
## `capsule`
|
|
446
|
+
|
|
447
|
+
| Field | Type | Default | Purpose |
|
|
448
|
+
| ------------- | -------------- | ------- | -------------------------------------------------------------------------------- |
|
|
449
|
+
| `enabled` | `boolean` | `false` | Initialise the DCA client. Required for any decryption to happen. |
|
|
450
|
+
| `clientBound` | `boolean` | `false` | Wrap the unlock key with RSA-OAEP for client-bound transport. |
|
|
451
|
+
| `rsaKeySize` | `2048 \| 4096` | `2048` | RSA key size when `clientBound` is `true`. |
|
|
452
|
+
| `autoProcess` | `boolean` | `true` | Auto-detect DCA manifests and decrypt on page load + observe for SPA navigation. |
|
|
453
|
+
|
|
454
|
+
When `enabled` is `true` the bootstrap loader pulls in
|
|
455
|
+
`@sesamy/sesamy-js/capsule-plugin` automatically. If you self-host, register
|
|
456
|
+
the plugin on `window.capsulePlugin` before sesamy-js auto-inits or pass it
|
|
457
|
+
via `init(config, { capsulePlugin })`.
|
|
10
458
|
|
|
11
|
-
|
|
459
|
+
## `consent`
|
|
12
460
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
461
|
+
| Field | Type | Default | Purpose |
|
|
462
|
+
| ----------------- | ------------------------------------------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
463
|
+
| `enabled` | `boolean` | — | Required. When `true`, analytics storage is gated on consent. |
|
|
464
|
+
| `cmp` | `'cookiebot' \| 'onetrust' \| 'google-consent-mode'` | — | Auto-integrate with the named consent management platform. |
|
|
465
|
+
| `defaultConsent` | `Partial<ConsentState>` | `{ statistics: false, marketing: false }` | Initial consent state before the CMP responds. |
|
|
466
|
+
| `onConsentChange` | `(update: (c: Partial<ConsentState>) => void) => void` | — | Custom CMP integration — the callback receives a function to push consent updates into sesamy-js. |
|
|
16
467
|
|
|
17
|
-
|
|
468
|
+
`ConsentState` has two fields: `statistics` and `marketing`. Read/write at
|
|
469
|
+
runtime via `sesamy.consent.get/set/has` — see [Consent](#consent-api) below.
|
|
18
470
|
|
|
19
|
-
|
|
471
|
+
## `awaitAllServices`
|
|
472
|
+
|
|
473
|
+
When `true`, the promise returned by `init()` resolves only after analytics,
|
|
474
|
+
auth, content, transforms, and capsule have finished initialising. Default
|
|
475
|
+
`false` so the page can keep rendering while those services start in the
|
|
476
|
+
background.
|
|
477
|
+
|
|
478
|
+
# Authentication configuration
|
|
479
|
+
|
|
480
|
+
## Custom domains
|
|
481
|
+
|
|
482
|
+
For a single custom Auth0 domain:
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
{
|
|
486
|
+
auth: {
|
|
487
|
+
clientId: 'your-client-id',
|
|
488
|
+
domain: 'auth.example.com',
|
|
489
|
+
},
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Multiple domains (multi-tenant / white-label)
|
|
494
|
+
|
|
495
|
+
For applications that operate across multiple domains, use the `domains`
|
|
496
|
+
array. The library extracts the top-level domain from the current page URL
|
|
497
|
+
and picks the matching entry; if no entry matches, it falls back to `domain`,
|
|
498
|
+
then to the default Sesamy auth domain.
|
|
499
|
+
|
|
500
|
+
```javascript
|
|
501
|
+
{
|
|
502
|
+
auth: {
|
|
503
|
+
clientId: 'your-client-id',
|
|
504
|
+
domains: [
|
|
505
|
+
'auth.brand1.com',
|
|
506
|
+
'auth.brand2.com',
|
|
507
|
+
'auth.example.co.uk',
|
|
508
|
+
],
|
|
509
|
+
domain: 'default-auth.example.com', // fallback if no match
|
|
510
|
+
},
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## Cross-domain authentication
|
|
515
|
+
|
|
516
|
+
When the application domain differs from the auth domain's top-level domain,
|
|
517
|
+
the library automatically uses popup-based login on Safari/iOS and Android
|
|
518
|
+
to handle the cross-domain cookies properly. Desktop browsers stay on
|
|
519
|
+
redirect-based login regardless.
|
|
520
|
+
|
|
521
|
+
| App domain | Auth domain | Mobile | Desktop |
|
|
522
|
+
| ----------------- | -------------------- | -------- | -------- |
|
|
523
|
+
| `app.example.com` | `auth.different.com` | Popup | Redirect |
|
|
524
|
+
| `app.example.com` | `auth.example.com` | Redirect | Redirect |
|
|
525
|
+
|
|
526
|
+
# API reference
|
|
527
|
+
|
|
528
|
+
All services hang off `window[namespace]` (default `window.sesamy`) and the
|
|
529
|
+
object returned by `init()`. The following methods are available — full
|
|
530
|
+
per-method documentation follows below.
|
|
20
531
|
|
|
21
532
|
- amendments
|
|
22
533
|
- create: create an amendment to a contract
|
|
@@ -28,12 +539,14 @@ The following methods are available on the `sesamy` object:
|
|
|
28
539
|
- set: set the attributions for a user
|
|
29
540
|
- auth
|
|
30
541
|
- getUser: fetches the user's profile
|
|
542
|
+
- getTokenSilently: retrieves a token without user interaction
|
|
31
543
|
- isAuthenticated: checks if the user is authenticated
|
|
32
544
|
- login: smart login that automatically chooses popup or redirect based on browser context
|
|
545
|
+
- loginWithPopup: opens a popup window to complete the login
|
|
33
546
|
- loginWithRedirect: redirects the user to the login page
|
|
34
547
|
- logout: logs the user out
|
|
35
|
-
-
|
|
36
|
-
-
|
|
548
|
+
- refresh: re-checks the authentication state from the auth provider
|
|
549
|
+
- setToken: stores a token in local storage and triggers the authenticated event
|
|
37
550
|
- bills
|
|
38
551
|
- get: get a bill by id
|
|
39
552
|
- list: lists all the user's bills
|
|
@@ -41,27 +554,43 @@ The following methods are available on the `sesamy` object:
|
|
|
41
554
|
- detectAdblock: detects if an ad blocker is enabled
|
|
42
555
|
- isInAppBrowser: detects if the browser is an in-app browser
|
|
43
556
|
- isIncognito: detects if the browser is in incognito mode
|
|
557
|
+
- capsule
|
|
558
|
+
- getClient: returns the underlying DCA client (when `capsule.enabled` is true)
|
|
559
|
+
- processPage: detect and decrypt every DCA manifest on the current page
|
|
44
560
|
- checkouts
|
|
45
561
|
- create: creates a checkout session
|
|
46
562
|
- get: gets a checkout session by id
|
|
47
563
|
- update: updates a checkout session
|
|
48
564
|
- clearCache: clears the cache for the sesamy-js library
|
|
565
|
+
- consent
|
|
566
|
+
- get: returns the current consent state
|
|
567
|
+
- has: checks whether a specific consent flag is granted
|
|
568
|
+
- set: updates the consent state and re-evaluates analytics storage
|
|
49
569
|
- content
|
|
50
|
-
- list: get all articles based on the configured selectors
|
|
51
570
|
- get: get an article based on an element or a selector
|
|
52
571
|
- getLanguage: get the current language
|
|
53
|
-
- unlock: retrieves the locked content using an element or a css selector
|
|
54
572
|
- getPropertyFromHTML: extracts a property from HTML content
|
|
573
|
+
- hasAccess: checks if the user has access to a specific article element
|
|
574
|
+
- list: get all articles based on the configured selectors
|
|
575
|
+
- showModal: opens the paywall modal (requires sesamy-components)
|
|
576
|
+
- showNotificationBar: shows an inline notification bar above/below content
|
|
577
|
+
- unlock: retrieves the locked content using an element or a css selector
|
|
55
578
|
- contracts
|
|
56
579
|
- cancel: cancel a contract by id
|
|
57
580
|
- get: get a contract by id
|
|
58
581
|
- list: lists all the user's contracts
|
|
582
|
+
- diagnostics
|
|
583
|
+
- collect: gathers a snapshot of profile, entitlements, contracts, tags, and tallies for support tickets
|
|
584
|
+
- send: collects diagnostics and uploads them to the Sesamy diagnostics endpoint
|
|
59
585
|
- entitlements
|
|
60
586
|
- access: fetches the user's access URL for an entitlement
|
|
61
587
|
- get: gets a single entitlement by id
|
|
62
588
|
- hasAccess: checks if the user has access to a specific item
|
|
63
589
|
- list: lists the user's entitlements
|
|
64
590
|
- signedLinks: lists signed links registered in the current session
|
|
591
|
+
- events
|
|
592
|
+
- cancel: cancels a cancelable event with an optional reason message
|
|
593
|
+
- emit: emits a custom event that can optionally be canceled by listeners
|
|
65
594
|
- flags
|
|
66
595
|
- get: gets a feature flag value
|
|
67
596
|
- set: sets a feature flag value
|
|
@@ -139,189 +668,6 @@ The library can trigger actions based on query parameters. The following query p
|
|
|
139
668
|
|
|
140
669
|
The library can read the access token from the hash. It is not the preferred way of logging in a user but can be used when redirecting the user across domains where a cookie-based solution is not possible. The hash is not sent to the server so the is no risk of leaking the token. The token hash is passed like this: `#access_token=<token>`
|
|
141
670
|
|
|
142
|
-
## Usage
|
|
143
|
-
|
|
144
|
-
The script can either be initiated with a JSON object in a script tag or by calling the init method.
|
|
145
|
-
|
|
146
|
-
The script will look for a script tag with the id `sesamy-js`, and if it isn't found it will wait for a call to the init function before initializing. The only required part is the `clientId` attribute.
|
|
147
|
-
|
|
148
|
-
```html
|
|
149
|
-
<script type="application/json" id="sesamy-js">
|
|
150
|
-
{
|
|
151
|
-
"clientId": "demo"
|
|
152
|
-
}
|
|
153
|
-
</script>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
These are the available configuration options, with their default values:
|
|
157
|
-
|
|
158
|
-
```javascript
|
|
159
|
-
{
|
|
160
|
-
clientId: null,
|
|
161
|
-
organization: null,
|
|
162
|
-
api: {
|
|
163
|
-
namespace: 'sesamy',
|
|
164
|
-
endpoint: 'https://api2.sesamy.com'
|
|
165
|
-
},
|
|
166
|
-
analytics: {
|
|
167
|
-
enabled: true,
|
|
168
|
-
endpoint: 'https://logs.sesamy.com/events'
|
|
169
|
-
},
|
|
170
|
-
auth: {
|
|
171
|
-
clientId: null,
|
|
172
|
-
organization: null,
|
|
173
|
-
enabled: true,
|
|
174
|
-
domain: null, // Optional: custom Auth0 domain (e.g., 'auth.example.com')
|
|
175
|
-
domains: [] // Optional: array of auth domain strings for multi-domain setups
|
|
176
|
-
},
|
|
177
|
-
content: [
|
|
178
|
-
{
|
|
179
|
-
type: 'article',
|
|
180
|
-
path: '/articles', // Optional: matches URLs containing this path
|
|
181
|
-
pass: 'premium', // Optional: pass requirement
|
|
182
|
-
price: { // Optional: price information
|
|
183
|
-
amount: 9.99,
|
|
184
|
-
currency: 'USD'
|
|
185
|
-
},
|
|
186
|
-
paywallUrl: 'https://example.com/paywall', // Optional: custom paywall URL
|
|
187
|
-
enablePaywallSettingsUrlFallback: false, // Optional: enable fallback to sesamy-paywall settings-url
|
|
188
|
-
selectors: {
|
|
189
|
-
article: { selector: 'article' },
|
|
190
|
-
image: { selector: 'img', attribute: 'src' },
|
|
191
|
-
title: { selector: 'h1', attribute: 'textContent' },
|
|
192
|
-
excerpt: { selector: 'p', attribute: 'textContent' },
|
|
193
|
-
price: { selector: 'article', attribute: 'data-price' },
|
|
194
|
-
currency: { selector: 'article', attribute: 'data-currency' },
|
|
195
|
-
url: { selector: 'link', attribute: 'href' },
|
|
196
|
-
id: { selector: 'article', attribute: 'data-id' },
|
|
197
|
-
pass: { selector: 'article', attribute: 'data-pass' },
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
],
|
|
201
|
-
tranforms: {
|
|
202
|
-
enabled: false,
|
|
203
|
-
rules: []
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
# Authentication Configuration
|
|
209
|
-
|
|
210
|
-
The `auth` configuration object controls how the Sesamy library handles user authentication. Below are the available options:
|
|
211
|
-
|
|
212
|
-
## Basic Configuration
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
{
|
|
216
|
-
auth: {
|
|
217
|
-
clientId: 'your-client-id', // Required: Your Auth0 client ID
|
|
218
|
-
organization: 'org_123', // Optional: Auth0 organization ID
|
|
219
|
-
enabled: true // Optional: Enable/disable authentication (default: true)
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Custom Domain Configuration
|
|
225
|
-
|
|
226
|
-
### Single Domain
|
|
227
|
-
|
|
228
|
-
For custom Auth0 domains, use the `domain` property:
|
|
229
|
-
|
|
230
|
-
```javascript
|
|
231
|
-
{
|
|
232
|
-
auth: {
|
|
233
|
-
clientId: 'your-client-id',
|
|
234
|
-
domain: 'auth.example.com' // Optional: Custom Auth0 domain
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Multiple Domains (Multi-tenant/White-label)
|
|
240
|
-
|
|
241
|
-
For applications that operate across multiple domains (e.g., white-label solutions, multi-region setups), use the `domains` array. The library will automatically select the appropriate auth domain based on the current page's top-level domain:
|
|
242
|
-
|
|
243
|
-
```javascript
|
|
244
|
-
{
|
|
245
|
-
auth: {
|
|
246
|
-
clientId: 'your-client-id',
|
|
247
|
-
domains: [
|
|
248
|
-
'auth.brand1.com',
|
|
249
|
-
'auth.brand2.com',
|
|
250
|
-
'auth.example.co.uk'
|
|
251
|
-
],
|
|
252
|
-
domain: 'default-auth.example.com' // Optional: fallback if no match found
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
**How it works:**
|
|
258
|
-
|
|
259
|
-
1. The library extracts the top-level domain from the current page URL
|
|
260
|
-
2. Each domain in the `domains` array is checked - the library derives its top-level domain (e.g., `auth.brand1.com` → `brand1.com`)
|
|
261
|
-
3. If the current page's top-level domain matches a domain in the array, that auth domain is used
|
|
262
|
-
4. If no match is found, it falls back to the `domain` property
|
|
263
|
-
5. If neither is available, it uses the default Sesamy auth domain
|
|
264
|
-
|
|
265
|
-
**Example scenarios:**
|
|
266
|
-
|
|
267
|
-
```javascript
|
|
268
|
-
// Multi-region setup
|
|
269
|
-
{
|
|
270
|
-
auth: {
|
|
271
|
-
clientId: 'your-client-id',
|
|
272
|
-
domains: [
|
|
273
|
-
'auth.us.example.com', // Used when on any *.example.com page
|
|
274
|
-
'auth.uk.example.co.uk', // Used when on any *.example.co.uk page
|
|
275
|
-
'auth.au.example.com.au' // Used when on any *.example.com.au page
|
|
276
|
-
]
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// White-label setup
|
|
281
|
-
{
|
|
282
|
-
auth: {
|
|
283
|
-
clientId: 'your-client-id',
|
|
284
|
-
domains: [
|
|
285
|
-
'auth.client1.com',
|
|
286
|
-
'auth.client2.com',
|
|
287
|
-
'auth.client3.com'
|
|
288
|
-
],
|
|
289
|
-
domain: 'auth.myplatform.com' // Default for unlisted domains
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
## Complete Example
|
|
295
|
-
|
|
296
|
-
```javascript
|
|
297
|
-
{
|
|
298
|
-
clientId: "demo",
|
|
299
|
-
organization: "org_abc123",
|
|
300
|
-
auth: {
|
|
301
|
-
clientId: "demo",
|
|
302
|
-
organization: "org_abc123",
|
|
303
|
-
enabled: true,
|
|
304
|
-
domains: [
|
|
305
|
-
'auth.example.com',
|
|
306
|
-
'auth.example.co.uk'
|
|
307
|
-
],
|
|
308
|
-
domain: 'auth.fallback.com'
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Cross-Domain Authentication
|
|
314
|
-
|
|
315
|
-
When your application domain differs from your Auth0 domain's top-level domain, the library automatically uses popup-based login on mobile browsers (Safari/iOS and Android) to handle cross-domain authentication properly. Desktop browsers will use redirect-based login even when cross-domain.
|
|
316
|
-
|
|
317
|
-
**Examples:**
|
|
318
|
-
|
|
319
|
-
- Your app: `app.example.com`, Auth domain: `auth.different.com`
|
|
320
|
-
- Mobile (Safari/iOS/Android): Popup login
|
|
321
|
-
- Desktop: Redirect login
|
|
322
|
-
- Your app: `app.example.com`, Auth domain: `auth.example.com` (same TLD)
|
|
323
|
-
- All browsers: Redirect login
|
|
324
|
-
|
|
325
671
|
# Custom HTML Attributes
|
|
326
672
|
|
|
327
673
|
## Visibility
|
|
@@ -702,6 +1048,26 @@ getTokenSilently()
|
|
|
702
1048
|
- If the publisher uses a custom domain for authentication (so the auth domain matches the publisher's top-level domain), the session token will be stored in an `httpOnly` cookie. In this case, malicious scripts can only access short-lived access tokens, not the session token itself.
|
|
703
1049
|
- Always ensure you trust third-party scripts running on your site, as they may be able to access tokens stored in local storage.
|
|
704
1050
|
|
|
1051
|
+
## `auth.refresh()`
|
|
1052
|
+
|
|
1053
|
+
Forces sesamy-js to re-check the authentication state from the configured auth
|
|
1054
|
+
plugin (Auth0 SPA or BFF cookie). Useful after an external login or logout has
|
|
1055
|
+
changed cookies/storage outside the SDK's awareness, or after a window
|
|
1056
|
+
re-focus where you suspect the session may have been invalidated server-side.
|
|
1057
|
+
|
|
1058
|
+
### Returns
|
|
1059
|
+
|
|
1060
|
+
`Promise<void>` — resolves once the auth state has been re-evaluated and any
|
|
1061
|
+
state-change events (`sesamyJsAuthenticated`, `sesamyJsLogout`) have fired.
|
|
1062
|
+
|
|
1063
|
+
### Example
|
|
1064
|
+
|
|
1065
|
+
```javascript
|
|
1066
|
+
window.addEventListener('focus', async () => {
|
|
1067
|
+
await window.sesamy.auth.refresh();
|
|
1068
|
+
});
|
|
1069
|
+
```
|
|
1070
|
+
|
|
705
1071
|
# Entitlements API
|
|
706
1072
|
|
|
707
1073
|
## `entitlements.get(entitlementId: string)`
|
|
@@ -1933,6 +2299,68 @@ async function unlockSpecificContent() {
|
|
|
1933
2299
|
}
|
|
1934
2300
|
```
|
|
1935
2301
|
|
|
2302
|
+
#### `content.showModal(options: ModalOptions)`
|
|
2303
|
+
|
|
2304
|
+
Opens the Sesamy paywall modal. Requires `sesamy-components` to be loaded
|
|
2305
|
+
(included by the bootstrap loader by default; otherwise load
|
|
2306
|
+
`@sesamy/open-web-components` yourself).
|
|
2307
|
+
|
|
2308
|
+
### Parameters
|
|
2309
|
+
|
|
2310
|
+
- `options` (`ModalOptions`):
|
|
2311
|
+
- `articleElementOrSelector` (`Element | string`, optional): Article whose
|
|
2312
|
+
metadata seeds the modal. Defaults to the first matched article.
|
|
2313
|
+
- `paywallId` (`string`, optional): Paywall configuration to render. Falls
|
|
2314
|
+
back to the article's `paywallUrl` selector.
|
|
2315
|
+
- `onClose` (`() => void`, optional): Called when the user dismisses the
|
|
2316
|
+
modal.
|
|
2317
|
+
|
|
2318
|
+
### Returns
|
|
2319
|
+
|
|
2320
|
+
- `Promise<ModalResult>`: Resolves with `{ action: 'purchased' | 'closed' | 'login' }`
|
|
2321
|
+
when the modal is closed.
|
|
2322
|
+
|
|
2323
|
+
### Example
|
|
2324
|
+
|
|
2325
|
+
```javascript
|
|
2326
|
+
const result = await window.sesamy.content.showModal({
|
|
2327
|
+
articleElementOrSelector: 'article#main',
|
|
2328
|
+
});
|
|
2329
|
+
|
|
2330
|
+
if (result.action === 'purchased') {
|
|
2331
|
+
await window.sesamy.content.unlock('article#main');
|
|
2332
|
+
}
|
|
2333
|
+
```
|
|
2334
|
+
|
|
2335
|
+
#### `content.showNotificationBar(options: NotificationBarOptions)`
|
|
2336
|
+
|
|
2337
|
+
Shows an inline notification bar pinned to the top or bottom of the viewport.
|
|
2338
|
+
Useful for unobtrusive prompts (e.g. "Subscribe for unlimited access") that
|
|
2339
|
+
don't block reading.
|
|
2340
|
+
|
|
2341
|
+
### Parameters
|
|
2342
|
+
|
|
2343
|
+
- `options` (`NotificationBarOptions`):
|
|
2344
|
+
- `position` (`'top' | 'bottom'`): Where to attach the bar.
|
|
2345
|
+
- `articleElementOrSelector` (`Element | string`, optional): Source of
|
|
2346
|
+
metadata.
|
|
2347
|
+
- `paywallId` (`string`, optional): Paywall configuration.
|
|
2348
|
+
- `onClose` (`() => void`, optional): Called on dismissal.
|
|
2349
|
+
|
|
2350
|
+
### Returns
|
|
2351
|
+
|
|
2352
|
+
- `Promise<NotificationBarResult>`: Resolves with the user action when the
|
|
2353
|
+
bar is dismissed.
|
|
2354
|
+
|
|
2355
|
+
### Example
|
|
2356
|
+
|
|
2357
|
+
```javascript
|
|
2358
|
+
window.sesamy.content.showNotificationBar({
|
|
2359
|
+
position: 'bottom',
|
|
2360
|
+
articleElementOrSelector: 'article#main',
|
|
2361
|
+
});
|
|
2362
|
+
```
|
|
2363
|
+
|
|
1936
2364
|
### Flags API
|
|
1937
2365
|
|
|
1938
2366
|
The Flags API allows for client-side feature flag management. These flags are stored in the browser's localStorage and can be used to enable or disable features for specific users.
|
|
@@ -2738,6 +3166,145 @@ window.sesamy.transactions
|
|
|
2738
3166
|
});
|
|
2739
3167
|
```
|
|
2740
3168
|
|
|
3169
|
+
# Capsule (DCA) API
|
|
3170
|
+
|
|
3171
|
+
Available when `capsule.enabled` is `true` in the config and the capsule
|
|
3172
|
+
plugin is registered (auto-loaded by the bootstrap, or registered via
|
|
3173
|
+
`window.capsulePlugin` / `init(config, { capsulePlugin })`).
|
|
3174
|
+
|
|
3175
|
+
## `capsule.processPage()`
|
|
3176
|
+
|
|
3177
|
+
Detects every DCA manifest currently in the DOM, calls the unlock endpoint
|
|
3178
|
+
for each, decrypts the payload, and injects the plaintext into the matching
|
|
3179
|
+
`data-dca-content-name` placeholder. Called automatically on page load when
|
|
3180
|
+
`capsule.autoProcess` is `true` (default) and again whenever the SPA mutates
|
|
3181
|
+
new DCA blocks into the DOM.
|
|
3182
|
+
|
|
3183
|
+
### Returns
|
|
3184
|
+
|
|
3185
|
+
`Promise<void>` — resolves once every detected manifest has been processed
|
|
3186
|
+
(or has failed gracefully).
|
|
3187
|
+
|
|
3188
|
+
### Example
|
|
3189
|
+
|
|
3190
|
+
```javascript
|
|
3191
|
+
// Manually retry decryption after a login completes
|
|
3192
|
+
window.addEventListener('sesamyJsAuthenticated', async () => {
|
|
3193
|
+
await window.sesamy.capsule.processPage();
|
|
3194
|
+
});
|
|
3195
|
+
```
|
|
3196
|
+
|
|
3197
|
+
## `capsule.getClient()`
|
|
3198
|
+
|
|
3199
|
+
Returns the underlying [`@sesamy/capsule`](https://www.npmjs.com/package/@sesamy/capsule)
|
|
3200
|
+
DCA client. Use this if you need lower-level access (custom resource fetchers,
|
|
3201
|
+
manual decryption, advanced introspection). Returns `undefined` when capsule
|
|
3202
|
+
is disabled or the plugin failed to load.
|
|
3203
|
+
|
|
3204
|
+
### Example
|
|
3205
|
+
|
|
3206
|
+
```javascript
|
|
3207
|
+
const dca = window.sesamy.capsule.getClient();
|
|
3208
|
+
const decoded = dca?.decodeManifest(rawManifest);
|
|
3209
|
+
```
|
|
3210
|
+
|
|
3211
|
+
# Consent API
|
|
3212
|
+
|
|
3213
|
+
Available always; gates analytics storage when `consent.enabled` is `true` in
|
|
3214
|
+
the config. Integrate with your CMP via the `consent.cmp` config or the
|
|
3215
|
+
`onConsentChange` callback, or drive consent imperatively from these
|
|
3216
|
+
functions.
|
|
3217
|
+
|
|
3218
|
+
## `consent.get()`
|
|
3219
|
+
|
|
3220
|
+
Returns the current consent state — an object with `statistics` and
|
|
3221
|
+
`marketing` booleans.
|
|
3222
|
+
|
|
3223
|
+
### Example
|
|
3224
|
+
|
|
3225
|
+
```javascript
|
|
3226
|
+
const state = window.sesamy.consent.get();
|
|
3227
|
+
if (state.statistics) {
|
|
3228
|
+
// analytics storage is allowed
|
|
3229
|
+
}
|
|
3230
|
+
```
|
|
3231
|
+
|
|
3232
|
+
## `consent.set(state: Partial<ConsentState>)`
|
|
3233
|
+
|
|
3234
|
+
Updates one or more consent flags and re-evaluates analytics storage
|
|
3235
|
+
immediately.
|
|
3236
|
+
|
|
3237
|
+
### Parameters
|
|
3238
|
+
|
|
3239
|
+
- `state` (`Partial<ConsentState>`): Partial consent object — only the keys
|
|
3240
|
+
you want to change need to be provided.
|
|
3241
|
+
|
|
3242
|
+
### Example
|
|
3243
|
+
|
|
3244
|
+
```javascript
|
|
3245
|
+
// User accepted statistics but not marketing
|
|
3246
|
+
window.sesamy.consent.set({ statistics: true, marketing: false });
|
|
3247
|
+
```
|
|
3248
|
+
|
|
3249
|
+
## `consent.has(type: 'statistics' | 'marketing')`
|
|
3250
|
+
|
|
3251
|
+
Returns `true` when the named consent flag is granted.
|
|
3252
|
+
|
|
3253
|
+
### Example
|
|
3254
|
+
|
|
3255
|
+
```javascript
|
|
3256
|
+
if (window.sesamy.consent.has('marketing')) {
|
|
3257
|
+
loadMarketingPixel();
|
|
3258
|
+
}
|
|
3259
|
+
```
|
|
3260
|
+
|
|
3261
|
+
# Diagnostics API
|
|
3262
|
+
|
|
3263
|
+
Tools to capture a snapshot of the user's runtime state for support tickets.
|
|
3264
|
+
Both methods read profile, entitlements, contracts, tags, and tallies via the
|
|
3265
|
+
already-initialised API.
|
|
3266
|
+
|
|
3267
|
+
## `diagnostics.collect(fallbackId?: string)`
|
|
3268
|
+
|
|
3269
|
+
Returns the diagnostics payload as an object without uploading it — useful if
|
|
3270
|
+
you want to render it in your own support form.
|
|
3271
|
+
|
|
3272
|
+
### Parameters
|
|
3273
|
+
|
|
3274
|
+
- `fallbackId` (`string`, optional): Identifier used in the payload when no
|
|
3275
|
+
authenticated user id is available.
|
|
3276
|
+
|
|
3277
|
+
### Returns
|
|
3278
|
+
|
|
3279
|
+
`Promise<DiagnosticsPayload>` — profile, entitlements, contracts, tags,
|
|
3280
|
+
tallies, library version, and environment metadata.
|
|
3281
|
+
|
|
3282
|
+
## `diagnostics.send(fallbackId?: string)`
|
|
3283
|
+
|
|
3284
|
+
Collects diagnostics and uploads them to the Sesamy diagnostics endpoint.
|
|
3285
|
+
Returns the diagnostics id you can paste into a support ticket.
|
|
3286
|
+
|
|
3287
|
+
### Parameters
|
|
3288
|
+
|
|
3289
|
+
- `fallbackId` (`string`, optional): Same as `collect`.
|
|
3290
|
+
|
|
3291
|
+
### Returns
|
|
3292
|
+
|
|
3293
|
+
`Promise<{ id: string }>`.
|
|
3294
|
+
|
|
3295
|
+
### Example
|
|
3296
|
+
|
|
3297
|
+
```javascript
|
|
3298
|
+
async function reportProblem() {
|
|
3299
|
+
const { id } = await window.sesamy.diagnostics.send();
|
|
3300
|
+
alert(`Diagnostics submitted — reference: ${id}`);
|
|
3301
|
+
}
|
|
3302
|
+
```
|
|
3303
|
+
|
|
3304
|
+
You can also trigger this without writing any code by appending
|
|
3305
|
+
`?sesamy-user-diagnostics=true` to the URL — sesamy-js will collect and
|
|
3306
|
+
submit automatically once initialisation completes.
|
|
3307
|
+
|
|
2741
3308
|
# Polyfills
|
|
2742
3309
|
|
|
2743
3310
|
The library polyfills the following methods for compatibility with older browsers:
|
|
@@ -2887,3 +3454,23 @@ const consumeUrl = client.links.generateConsumeLink(
|
|
|
2887
3454
|
|
|
2888
3455
|
- **sesamy-js `generateLink`**: Includes authentication token in hash if user is authenticated, automatically includes tracking cookies and attribution data, supports link shortening via TTL
|
|
2889
3456
|
- **SDK `links.*`**: Pure URL generation without authentication, useful for generating shareable links, links for unauthenticated users, or backend link generation
|
|
3457
|
+
|
|
3458
|
+
# Debugging
|
|
3459
|
+
|
|
3460
|
+
sesamy-js has several debug surfaces that are off by default and zero-cost
|
|
3461
|
+
when off:
|
|
3462
|
+
|
|
3463
|
+
- **Verbose runtime logs.** Append `?sesamy-debug=true` to the URL or set
|
|
3464
|
+
`localStorage.debug = true`. Calls to `sesamy.log(...)` and the SDK's
|
|
3465
|
+
internal logger flush to the console.
|
|
3466
|
+
- **Bootstrap logs.** Pass `debug: true` to `sesamyBootstrap(...)` (or the
|
|
3467
|
+
bootstrap config element). Emits `[sesamy-boot]` lines for chain entry
|
|
3468
|
+
selection, userinfo prefetch source, script load/error events, and
|
|
3469
|
+
fallback trigger reasons. Useful for diagnosing chain regressions without
|
|
3470
|
+
a HAR capture.
|
|
3471
|
+
- **User diagnostics.** Append `?sesamy-user-diagnostics=true` to collect a
|
|
3472
|
+
snapshot of profile, entitlements, contracts, tags, and tallies and upload
|
|
3473
|
+
it to the Sesamy diagnostics endpoint. The payload id is logged to the
|
|
3474
|
+
console for support tickets — see [Diagnostics API](#diagnostics-api).
|
|
3475
|
+
- **Library version.** `sesamy.getVersion()` returns the running version, in
|
|
3476
|
+
case multiple bundles end up on the page.
|