@schibsted/account-sdk-browser 5.2.7 → 6.0.0-alpha.10

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.
Files changed (109) hide show
  1. package/README.md +46 -301
  2. package/dist/account-sdk.d.ts +22 -0
  3. package/dist/account.d.ts +179 -0
  4. package/dist/cache.d.ts +65 -0
  5. package/dist/config.d.ts +86 -0
  6. package/dist/globals.d.ts +11 -0
  7. package/dist/has-access-response.d.ts +2 -0
  8. package/dist/identity.d.ts +302 -0
  9. package/dist/index.d.ts +11 -0
  10. package/dist/index.js +828 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/monetization.d.ts +39 -0
  13. package/{src → dist}/object.d.ts +4 -9
  14. package/dist/popup.d.ts +9 -0
  15. package/dist/resolve-browser-window.d.ts +1 -0
  16. package/dist/rest-client.d.ts +102 -0
  17. package/dist/rest-clients.d.ts +10 -0
  18. package/dist/sdk-error.d.ts +29 -0
  19. package/dist/session-response.d.ts +54 -0
  20. package/{src/spidTalk.d.ts → dist/spid-talk.d.ts} +4 -6
  21. package/dist/types/account.d.ts +48 -0
  22. package/dist/types/common.d.ts +28 -0
  23. package/dist/types/identity.d.ts +23 -0
  24. package/dist/types/login.d.ts +125 -0
  25. package/dist/types/monetization.d.ts +26 -0
  26. package/dist/types/session.d.ts +146 -0
  27. package/dist/url.d.ts +8 -0
  28. package/dist/validate.d.ts +50 -0
  29. package/dist/version.d.ts +2 -0
  30. package/package.json +34 -52
  31. package/src/account-sdk.ts +92 -0
  32. package/src/account.ts +332 -0
  33. package/src/{cache.js → cache.ts} +53 -38
  34. package/src/{config.js → config.ts} +7 -32
  35. package/src/globals.ts +8 -0
  36. package/src/has-access-response.ts +35 -0
  37. package/src/identity.ts +1023 -0
  38. package/src/index.ts +40 -0
  39. package/src/monetization.ts +128 -0
  40. package/src/{object.js → object.ts} +9 -16
  41. package/src/popup.ts +74 -0
  42. package/src/resolve-browser-window.ts +11 -0
  43. package/src/rest-client.ts +253 -0
  44. package/src/rest-clients.ts +30 -0
  45. package/src/sdk-error.ts +61 -0
  46. package/src/session-response.ts +100 -0
  47. package/src/{spidTalk.js → spid-talk.ts} +10 -12
  48. package/src/types/account.ts +55 -0
  49. package/src/types/common.ts +32 -0
  50. package/src/types/identity.ts +26 -0
  51. package/src/types/login.ts +150 -0
  52. package/src/types/monetization.ts +29 -0
  53. package/src/types/session.ts +169 -0
  54. package/src/{url.js → url.ts} +6 -10
  55. package/src/{validate.js → validate.ts} +27 -43
  56. package/src/{version.js → version.ts} +1 -2
  57. package/es5/global.js +0 -12968
  58. package/es5/global.js.map +0 -1
  59. package/es5/global.min.js +0 -2
  60. package/es5/global.min.js.map +0 -1
  61. package/es5/identity.js +0 -12212
  62. package/es5/identity.js.map +0 -1
  63. package/es5/identity.min.js +0 -2
  64. package/es5/identity.min.js.map +0 -1
  65. package/es5/index.js +0 -12940
  66. package/es5/index.js.map +0 -1
  67. package/es5/index.min.js +0 -2
  68. package/es5/index.min.js.map +0 -1
  69. package/es5/monetization.js +0 -9176
  70. package/es5/monetization.js.map +0 -1
  71. package/es5/monetization.min.js +0 -2
  72. package/es5/monetization.min.js.map +0 -1
  73. package/es5/payment.js +0 -8853
  74. package/es5/payment.js.map +0 -1
  75. package/es5/payment.min.js +0 -2
  76. package/es5/payment.min.js.map +0 -1
  77. package/identity.d.ts +0 -1
  78. package/identity.js +0 -5
  79. package/index.d.ts +0 -4
  80. package/index.js +0 -9
  81. package/monetization.d.ts +0 -1
  82. package/monetization.js +0 -5
  83. package/payment.d.ts +0 -1
  84. package/payment.js +0 -5
  85. package/src/RESTClient.d.ts +0 -89
  86. package/src/RESTClient.js +0 -193
  87. package/src/SDKError.d.ts +0 -16
  88. package/src/SDKError.js +0 -55
  89. package/src/__mocks__/.eslintrc.yml +0 -8
  90. package/src/__mocks__/RESTClient.js +0 -54
  91. package/src/cache.d.ts +0 -64
  92. package/src/config.d.ts +0 -34
  93. package/src/es5/global.js +0 -13
  94. package/src/es5/identity.js +0 -10
  95. package/src/es5/index.js +0 -13
  96. package/src/es5/monetization.js +0 -10
  97. package/src/es5/payment.js +0 -10
  98. package/src/global-registry.js +0 -20
  99. package/src/identity.d.ts +0 -679
  100. package/src/identity.js +0 -1157
  101. package/src/monetization.d.ts +0 -80
  102. package/src/monetization.js +0 -172
  103. package/src/payment.d.ts +0 -115
  104. package/src/payment.js +0 -211
  105. package/src/popup.d.ts +0 -10
  106. package/src/popup.js +0 -59
  107. package/src/url.d.ts +0 -10
  108. package/src/validate.d.ts +0 -64
  109. package/src/version.d.ts +0 -2
@@ -0,0 +1,100 @@
1
+ /* Copyright 2026 Schibsted Products & Technology AS. Licensed under the terms of the MIT license.
2
+ * See LICENSE.md in the project root.
3
+ */
4
+
5
+ import type {
6
+ ConnectedSessionResponse,
7
+ ConnectedSessionWithUserIdResponse,
8
+ NormalizedSessionPayload,
9
+ RedirectSessionPayload,
10
+ SessionFailureResponse,
11
+ SessionResponse,
12
+ SessionSuccessResponse,
13
+ } from './types/session.js';
14
+ import { isObject, isStr } from './validate.js';
15
+
16
+ /**
17
+ * Checks whether a value is a successful session response.
18
+ *
19
+ * @param value - The value to check.
20
+ * @group Session
21
+ */
22
+ export function isSessionSuccessResponse(value: unknown): value is SessionSuccessResponse {
23
+ return isObject(value) && typeof value.result === 'boolean';
24
+ }
25
+
26
+ /**
27
+ * Checks whether a successful session response represents a user connected to the merchant.
28
+ *
29
+ * @param value - The value to check.
30
+ * @group Session
31
+ */
32
+ export function isConnectedSessionResponse(value: unknown): value is ConnectedSessionResponse {
33
+ return isSessionSuccessResponse(value) && value.result === true;
34
+ }
35
+
36
+ /**
37
+ * Checks whether a value is a session failure response.
38
+ *
39
+ * @param value - The value to check.
40
+ * @group Session
41
+ */
42
+ export function isSessionFailureResponse(value: unknown): value is SessionFailureResponse {
43
+ return isObject(value) && Boolean(value.error);
44
+ }
45
+
46
+ export function isRedirectSessionPayload(value: unknown): value is RedirectSessionPayload {
47
+ return isObject(value) && Object.keys(value).length === 1 && isStr(value.redirectURL);
48
+ }
49
+
50
+ /**
51
+ * Checks whether a connected session response contains a usable user id.
52
+ *
53
+ * @param value - The value to check.
54
+ * @group Session
55
+ */
56
+ export function isConnectedSessionWithUserIdResponse(
57
+ value: SessionResponse,
58
+ ): value is ConnectedSessionWithUserIdResponse {
59
+ return isConnectedSessionResponse(value) && typeof value.userId === 'number';
60
+ }
61
+
62
+ /**
63
+ * Converts an unknown Session Service `hasSession` payload into one of the shapes the SDK knows how
64
+ * to handle.
65
+ *
66
+ * This function is intentionally tolerant because `hasSession()` historically resolved unknown
67
+ * object payloads instead of rejecting them. The SDK relies on that behavior for backwards
68
+ * compatibility with clients that check the raw response themselves.
69
+ *
70
+ * The normal cases are:
71
+ * - regular success payloads with a boolean `result`;
72
+ * - failure payloads wrapped as `{ error, response? }`;
73
+ * - Safari/session-refresh redirect payloads shaped as `{ redirectURL }`.
74
+ *
75
+ * Any other object is preserved as an unrecognized response so callers can still receive it.
76
+ * Non-object values are normalized to `{}`, matching the old "empty response" fallback used by
77
+ * `hasSession()` and cached-session reads.
78
+ *
79
+ * This is used both for network responses parsed by `RESTClient` and for values restored from the
80
+ * session cache, so the rest of the Identity flow can switch on typed guards instead of repeatedly
81
+ * re-validating unknown data.
82
+ *
83
+ * @internal
84
+ */
85
+ export function normalizeSessionResponse(value: unknown): NormalizedSessionPayload {
86
+ if (isRedirectSessionPayload(value)) {
87
+ return value;
88
+ }
89
+ if (isSessionFailureResponse(value)) {
90
+ return value;
91
+ }
92
+ if (isSessionSuccessResponse(value)) {
93
+ return value;
94
+ }
95
+ if (isObject(value)) {
96
+ return value;
97
+ }
98
+
99
+ return {};
100
+ }
@@ -2,13 +2,12 @@
2
2
  * See LICENSE.md in the project root.
3
3
  */
4
4
 
5
- 'use strict';
6
-
7
5
  /**
8
6
  * A workaround for how Schibsted account handles JSONP calls in the browser
9
7
  * @private
10
8
  */
11
9
 
10
+ import './globals.js';
12
11
  import { isFunction } from './validate.js';
13
12
 
14
13
  /**
@@ -20,20 +19,19 @@ import { isFunction } from './validate.js';
20
19
  * The old SPiD JSONP APIs relied on SPiD.Talk.response(callbackName, data) but fetch-jsonp merely
21
20
  * calls window[callbackName](data) which is more common practice. This module simply acts as an
22
21
  * adapter to modernize the old mechanism until we support CORS. To see how the SPiD solution works,
23
- * try to run a simple JSONP request or debug it in netowrk tab. This module will be removed when
24
- * CORS is supported.
25
- * @memberof core
26
- * @param {object} global - a reference to the global object
27
- * @return {void}
22
+ * try to run a simple JSONP request or debug it in the network tab. This module will be removed
23
+ * when CORS is supported.
24
+ * @param global - A reference to the global object, typically the `Window`.
28
25
  */
29
- export function emulate(global) {
30
- if (global.SPiD === null || typeof global.SPiD !== 'object') {
26
+ export function emulate(global: Window): void {
27
+ if (!global.SPiD || typeof global.SPiD !== 'object') {
31
28
  global.SPiD = {};
32
29
  }
33
- if (global.SPiD.Talk === null || typeof global.SPiD.Talk !== 'object') {
34
- global.SPiD.Talk = {}
30
+ if (!global.SPiD.Talk || typeof global.SPiD.Talk !== 'object') {
31
+ global.SPiD.Talk = {};
35
32
  }
36
33
  if (!isFunction(global.SPiD.Talk.response)) {
37
- global.SPiD.Talk.response = (callbackName, data) => global[callbackName](data);
34
+ global.SPiD.Talk.response = (callbackName: string, data: unknown) =>
35
+ (global as any)[callbackName](data);
38
36
  }
39
37
  }
@@ -0,0 +1,55 @@
1
+ import type { AccountBaseConfig, LogFunction } from './common';
2
+ import type { IdentityBeforeRedirectCallback, VarnishCookieOptions } from './identity';
3
+ import type { SessionResponse } from './session';
4
+
5
+ /**
6
+ * Configuration used to create an {@link Account} instance.
7
+ *
8
+ * @group Configuration
9
+ */
10
+ export type AccountConfig = AccountBaseConfig & {
11
+ /** Receives debug log information. If not set, no logging will be done. */
12
+ log?: LogFunction;
13
+ /** Callback triggered before a session refresh redirect happens. */
14
+ callbackBeforeRedirect?: IdentityBeforeRedirectCallback;
15
+ /** Product or feature ids used by `hasAccess()` when no ids are passed to the method. */
16
+ defaultProductIds?: string[];
17
+ /** Optional Varnish cookie setup applied during Account initialization. */
18
+ varnish?: VarnishCookieOptions;
19
+ };
20
+
21
+ type LoginRequestedEventDetail = {
22
+ url: string;
23
+ method: 'popup' | 'default';
24
+ };
25
+
26
+ type LogoutRequestedEventDetail = {
27
+ url: string;
28
+ };
29
+
30
+ export type AccountEventMap = {
31
+ /** Emitted with the login URL and method when `login()` initiates a login flow. */
32
+ loginRequested: CustomEvent<LoginRequestedEventDetail>;
33
+ /** Emitted with the logout URL when `logout()` is called. */
34
+ logoutRequested: CustomEvent<LogoutRequestedEventDetail>;
35
+ /** Emitted when `hasSession()` detects a change in the stored session state. */
36
+ sessionUpdated: CustomEvent<SessionResponse>;
37
+ /** Emitted when the simplified login widget is displayed. */
38
+ simplifiedLoginOpened: Event;
39
+ /** Emitted when the simplified login widget is closed. */
40
+ simplifiedLoginCancelled: Event;
41
+ };
42
+
43
+ /** Account event names emitted by the SDK. */
44
+ export type AccountEventName = keyof AccountEventMap;
45
+
46
+ /**
47
+ * Native event listener used by Account event subscriptions.
48
+ *
49
+ * Payload-bearing events are `CustomEvent` instances and expose their payload through `detail`.
50
+ *
51
+ * @group Events
52
+ */
53
+ export type AccountEventListener<EventName extends AccountEventName = AccountEventName> = (
54
+ event: AccountEventMap[EventName],
55
+ ) => void;
@@ -0,0 +1,32 @@
1
+ /* Common types used across the SDK */
2
+
3
+ /**
4
+ * Log callback used by the SDK for debug output.
5
+ * Receives a pre-formatted log line.
6
+ *
7
+ * @group Configuration
8
+ */
9
+ export type LogFunction = (message: string) => void;
10
+
11
+ /**
12
+ * Supported Schibsted account environment keys.
13
+ *
14
+ * @group Configuration
15
+ */
16
+ export type AccountEnvironment = 'LOCAL' | 'DEV' | 'PRE' | 'PRO' | 'PRO_NO' | 'PRO_FI' | 'PRO_DK';
17
+
18
+ /**
19
+ * Shared Account configuration fields.
20
+ */
21
+ export type AccountBaseConfig = {
22
+ /** Mandatory client id. Example: "1234567890abcdef12345678" */
23
+ clientId: string;
24
+ /** Redirect uri. Example: "https://site.com" */
25
+ redirectUri: string;
26
+ /** Session Service domain. Example: "https://id.site.com" */
27
+ sessionDomain: string;
28
+ /** Schibsted account environment. Defaults to PRE. */
29
+ env?: AccountEnvironment;
30
+ /** Window object to use. Defaults to the global `window`. */
31
+ window?: Window;
32
+ };
@@ -0,0 +1,26 @@
1
+ import type { AccountBaseConfig, LogFunction } from './common';
2
+
3
+ /**
4
+ * Callback invoked before the SDK performs a full-page session refresh redirect.
5
+ */
6
+ export type IdentityBeforeRedirectCallback = () => void | Promise<void>;
7
+
8
+ /**
9
+ * Options accepted by the {@link Identity} constructor.
10
+ */
11
+ export type IdentityOptions = AccountBaseConfig & {
12
+ /** Receives debug log information. If not set, no logging will be done. */
13
+ log?: LogFunction;
14
+ /** Callback triggered before a session refresh redirect happens. */
15
+ callbackBeforeRedirect?: IdentityBeforeRedirectCallback;
16
+ };
17
+
18
+ /**
19
+ * Options for {@link Identity#enableVarnishCookie}.
20
+ */
21
+ export type VarnishCookieOptions = {
22
+ /** Override number of seconds before the Varnish cookie expires. */
23
+ expiresIn?: number;
24
+ /** Override cookie domain. E.g. "vg.no" instead of "www.vg.no". */
25
+ domain?: string;
26
+ };
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Options accepted by {@link Account#login} and related login URL helpers.
3
+ *
4
+ * @group Login & Widget
5
+ */
6
+ export type LoginOptions = {
7
+ /**
8
+ * An opaque value used by the client to maintain state between the request and callback.
9
+ * It's also recommended to prevent CSRF {@link https://tools.ietf.org/html/rfc6749#section-10.12}
10
+ */
11
+ state: string;
12
+ /**
13
+ * Authentication Context Class Reference values. If omitted, the default account flow is used.
14
+ * Supported values include `password`, `otp`, `sms`, `otp-email`, `eid`, `eid-no`, `eid-se`,
15
+ * `eid-fi`, and `eid-dk`. Values other than `otp-email` may be combined as a space-separated
16
+ * string. Verify the AMR (Authentication Methods References) claim in the ID token on your
17
+ * backend if you need to enforce a completed authentication method.
18
+ */
19
+ acrValues?:
20
+ | 'password'
21
+ | 'otp'
22
+ | 'sms'
23
+ | 'eid-dk'
24
+ | 'eid-no'
25
+ | 'eid-se'
26
+ | 'eid-fi'
27
+ | 'eid'
28
+ | 'otp-email'
29
+ | (string & {});
30
+ /**
31
+ * The OAuth scopes for the tokens. This is a list of scopes, separated by space. If the list
32
+ * of scopes contains `openid`, the generated tokens includes the id token which can be useful
33
+ * for getting information about the user. Omitting scope is allowed, while `invalid_scope` is
34
+ * returned when the client asks for a scope you aren't allowed to request.
35
+ * {@link https://tools.ietf.org/html/rfc6749#section-3.3}
36
+ * Defaults to `openid`.
37
+ */
38
+ scope?: 'openid' | (string & {});
39
+ /**
40
+ * Redirect uri that will receive the code. Must exactly match a redirectUri from your client
41
+ * in self-service
42
+ */
43
+ redirectUri?: string;
44
+ /** Should we try to open a popup window? Defaults to `false`. */
45
+ preferPopup?: boolean;
46
+ /** user email or UUID hint */
47
+ loginHint?: string;
48
+ /** Pulse tag */
49
+ tag?: string;
50
+ /** Teaser slug. Teaser with given slug will be displayed in place of default teaser */
51
+ teaser?: string;
52
+ /**
53
+ * Specifies the allowable elapsed time in seconds since the last time the End-User was actively
54
+ * authenticated. If last authentication time is more than maxAge seconds in the past,
55
+ * re-authentication will be required. See the OpenID Connect spec section 3.1.2.1 for more
56
+ * information. Prefer a number of seconds; strings remain accepted for legacy callers.
57
+ */
58
+ maxAge?: number | string;
59
+ /**
60
+ * Optional parameter to overwrite client locale setting.
61
+ * New flows supports nb_NO, fi_FI, sv_SE, en_US
62
+ */
63
+ locale?: 'nb_NO' | 'fi_FI' | 'sv_SE' | 'en_US';
64
+ /** display username and password on one screen. Defaults to `false`. */
65
+ oneStepLogin?: boolean;
66
+ /**
67
+ * String that specifies whether the Authorization Server prompts the End-User for
68
+ * reauthentication or confirm account screen. Supported values: `select_account` or `login`.
69
+ * Defaults to `select_account`.
70
+ */
71
+ prompt?: 'select_account' | 'login';
72
+ /** Identifier for cross-domain tracking in Pulse */
73
+ xDomainId?: string;
74
+ /** Environment for cross-domain tracking in Pulse */
75
+ xEnvironmentId?: string;
76
+ /** Campaign identifier for tracking in Pulse */
77
+ originCampaign?: string;
78
+ };
79
+
80
+ /**
81
+ * Identical to {@link LoginOptions} except that `state` may also be a (possibly async) function;
82
+ * all other fields reuse the `LoginOptions` documentation.
83
+ *
84
+ * @group Login & Widget
85
+ */
86
+ export type SimplifiedLoginWidgetLoginOptions = Omit<LoginOptions, 'state'> & {
87
+ /**
88
+ * An opaque value used by the client to maintain state between the request and callback.
89
+ * It's also recommended to prevent CSRF {@link https://tools.ietf.org/html/rfc6749#section-10.12}
90
+ */
91
+ state: string | (() => string | Promise<string>);
92
+ };
93
+
94
+ /**
95
+ * Minimal user information used by the simplified login widget flow.
96
+ *
97
+ * @group Login & Widget
98
+ */
99
+ export type SimplifiedLoginData = {
100
+ /** Deprecated: User UUID used as `loginHint` for {@link Account#login}. */
101
+ identifier: string;
102
+ /** Human-readable user identifier */
103
+ display_text: string;
104
+ /** Client name */
105
+ client_name: string;
106
+ /** Provider id used by the simplified login widget when supplied by the backend. */
107
+ provider_id?: string;
108
+ };
109
+
110
+ /**
111
+ * Configuration options for {@link Account#showSimplifiedLoginWidget}.
112
+ *
113
+ * @group Login & Widget
114
+ */
115
+ export type SimplifiedLoginWidgetOptions = {
116
+ /** expected encoding of simplified login widget. Could be utf-8 (default), iso-8859-1 or iso-8859-15 */
117
+ encoding?: string;
118
+ /**
119
+ * expected locale of simplified login widget. Should be provided in a short format like 'nb',
120
+ * 'sv'. If not set, a value from the env variable is used.
121
+ */
122
+ locale?: 'nb' | 'sv' | 'fi' | 'da' | 'en';
123
+ };
124
+
125
+ export type SimplifiedLoginWidgetInitialParams = {
126
+ displayText: string;
127
+ env: string;
128
+ clientName: string;
129
+ clientId: string;
130
+ providerId?: string;
131
+ locale?: SimplifiedLoginWidgetOptions['locale'];
132
+ windowWidth: () => number;
133
+ windowOnResize: (handler: () => void) => void;
134
+ };
135
+
136
+ export type SimplifiedLoginWidgetHandler = () => void | Promise<void>;
137
+
138
+ export type OpenSimplifiedLoginWidget = (
139
+ initialParams: SimplifiedLoginWidgetInitialParams,
140
+ loginHandler: SimplifiedLoginWidgetHandler,
141
+ loginNotYouHandler: SimplifiedLoginWidgetHandler,
142
+ initHandler: SimplifiedLoginWidgetHandler,
143
+ cancelLoginHandler: SimplifiedLoginWidgetHandler,
144
+ ) => unknown;
145
+
146
+ export const hasOpenSimplifiedLoginWidget = (
147
+ targetWindow: Window,
148
+ ): targetWindow is Window & { openSimplifiedLoginWidget: OpenSimplifiedLoginWidget } => {
149
+ return typeof targetWindow.openSimplifiedLoginWidget === 'function';
150
+ };
@@ -0,0 +1,29 @@
1
+ import type { AccountBaseConfig } from './common';
2
+ import type { SessionUserId } from './session';
3
+
4
+ /**
5
+ * Result returned by the Session Service `/hasAccess` endpoint, describing whether the user
6
+ * is entitled to a requested set of products/features.
7
+ *
8
+ * @group Access Checks
9
+ */
10
+ export interface HasAccessResult {
11
+ /** Whether the user is entitled to at least one of the requested products/features. */
12
+ entitled: boolean;
13
+ /** How long this result stays valid, in seconds, before the cache entry expires. */
14
+ ttl: number;
15
+ /** Feature ids the user is allowed to access. */
16
+ allowedFeatures: string[];
17
+ /** User id the access result belongs to. */
18
+ userId: SessionUserId;
19
+ /** Globally unique user id the access result belongs to. */
20
+ uuid: string;
21
+ /** Signed response payload. */
22
+ sig: string;
23
+ }
24
+
25
+ /**
26
+ * Options accepted by the {@link Monetization} constructor.
27
+ */
28
+ export type MonetizationOptions = Pick<AccountBaseConfig, 'clientId' | 'env' | 'window'> &
29
+ Partial<Pick<AccountBaseConfig, 'redirectUri' | 'sessionDomain'>>;
@@ -0,0 +1,169 @@
1
+ /* Copyright 2026 Schibsted Products & Technology AS. Licensed under the terms of the MIT license.
2
+ * See LICENSE.md in the project root.
3
+ */
4
+
5
+ /**
6
+ * Numeric Schibsted Account user id.
7
+ *
8
+ * @group Session
9
+ */
10
+ export type SessionUserId = number;
11
+
12
+ // Session Service object payloads.
13
+
14
+ /**
15
+ * Successful response returned from {@link Account#hasSession}.
16
+ *
17
+ * `result` means the has-session call itself succeeded. `result: true` means the user is
18
+ * connected to the merchant; `result: false` means a session may exist, but the user is not
19
+ * connected to this client.
20
+ *
21
+ * @group Session
22
+ */
23
+ export type SessionSuccessResponse = {
24
+ /** Response status code. Example: 200. */
25
+ code?: number;
26
+ /** Response type. Example: 'OK'. */
27
+ type?: string;
28
+ /** Human-readable response description. Example: 'OK'. */
29
+ description?: string;
30
+ /**
31
+ * Is the user connected to the merchant? This means the merchant id is in the list of
32
+ * merchants connected to this user.
33
+ */
34
+ result: boolean;
35
+ /** Connection status string. Deprecated; use `Account.isConnected()`. Example: 'connected'. */
36
+ userStatus?: string;
37
+ /** Cookie base domain used as the `SP_ID` cookie domain fallback. Example: 'spid.no'. */
38
+ baseDomain?: string;
39
+ /** Legacy session id. Obsolete. Example: '58eca10fdbb9f6df72c3368f'. */
40
+ id?: string;
41
+ /** A numeric user id which is unique per realm (country). Example: 37162 */
42
+ userId?: SessionUserId;
43
+ /** Globally unique user id. Example: 'b3b23aa7-34f2-5d02-a10e-5a3455c6ab2c' */
44
+ uuid?: string;
45
+ /** Session token used for the `SP_ID` cookie. Example: 'eyJjbGllbnRfaWQ...'. */
46
+ sp_id?: string;
47
+ /** Session response TTL in seconds. Example: 300. */
48
+ expiresIn?: number;
49
+ /** Server time as a Unix timestamp in seconds. Example: 1506285759. */
50
+ serverTime?: number;
51
+ /**
52
+ * Example: 'NCdzXaz4ZRb7...' The sig parameter is a concatenation of an HMAC SHA-256
53
+ * signature string, a dot (.) and a base64url encoded JSON object (session).
54
+ * {@link http://techdocs.spid.no/sdks/js/response-signature-and-validation/}
55
+ */
56
+ sig?: string;
57
+ /** User display name. Example: 'batman'. */
58
+ displayName?: string;
59
+ /** User given name. Example: 'Bruce'. */
60
+ givenName?: string;
61
+ /** User family name. Example: 'Wayne'. */
62
+ familyName?: string;
63
+ /** User gender value. Example: 'male', 'female', 'undisclosed'. */
64
+ gender?: string;
65
+ /** User profile photo URL. Example: 'http://www.srv.com/some/picture.jpg' . */
66
+ photo?: string;
67
+ /** Whether tracking is enabled for this session. Example: true. */
68
+ tracking?: boolean;
69
+ /** Whether the client agreement is accepted. Example: true. */
70
+ clientAgreementAccepted?: boolean;
71
+ /** Whether the default agreement is accepted. Example: true. */
72
+ defaultAgreementAccepted?: boolean;
73
+ /** Pairwise user id for this client. Example: 'b2a23caa...'. */
74
+ pairId?: string;
75
+ /** User SDRN. Example: 'sdrn:spid.no:user:12345'. */
76
+ sdrn?: string;
77
+ };
78
+
79
+ /**
80
+ * Successful has-session response for a user connected to the merchant.
81
+ *
82
+ * @group Session
83
+ */
84
+ export type ConnectedSessionResponse = SessionSuccessResponse & {
85
+ result: true;
86
+ };
87
+
88
+ /**
89
+ * Connected session response that also carries a usable user id.
90
+ *
91
+ * @group Session
92
+ */
93
+ export type ConnectedSessionWithUserIdResponse = ConnectedSessionResponse & {
94
+ userId: SessionUserId;
95
+ };
96
+
97
+ /**
98
+ * Failure payload returned by Session Service.
99
+ *
100
+ * API and network failures usually reject with {@link SDKError}; this shape represents a failure
101
+ * payload when one is returned by Session Service and reaches the has-session flow.
102
+ *
103
+ * @group Session
104
+ */
105
+ export type SessionFailureResponse = {
106
+ /** Failure payload returned by Session Service. Usually an object, but tests also pass strings. */
107
+ error: string | number | boolean | object;
108
+ response?: {
109
+ /** Response status code. Example: 404. */
110
+ code: number;
111
+ /** Response type. Example: 'NOT_FOUND'. */
112
+ type: string;
113
+ /** Human-readable response description. Example: 'No session found'. */
114
+ description: string;
115
+ /** Cookie base domain used as the `SP_ID` cookie domain fallback. Example: 'spid.no'. */
116
+ baseDomain?: string;
117
+ /** Time span in milliseconds. Example: 30 * 60 * 1000 (for 30 minutes) */
118
+ expiresIn?: number;
119
+ result?: boolean;
120
+ /** Server time in seconds since the Unix Epoch. Example: 1506287788 */
121
+ serverTime?: number;
122
+ [key: string]: string | number | boolean | object | null | undefined;
123
+ };
124
+ };
125
+
126
+ /**
127
+ * Object response that does not match one of the SDK-known has-session shapes.
128
+ *
129
+ * This intentionally includes `{}`. Historically `hasSession()` could resolve an empty object or
130
+ * other object payloads that callers inspected themselves, so the SDK preserves those responses.
131
+ *
132
+ * @group Session
133
+ */
134
+ export type UnrecognizedSessionResponse = object;
135
+
136
+ /**
137
+ * Redirect URL returned by `hasSession()` when Session Service needs a full-page session refresh.
138
+ *
139
+ * @group Session
140
+ */
141
+ export type RedirectSessionResponse = string;
142
+
143
+ export type SessionObjectResponse =
144
+ | SessionSuccessResponse
145
+ | SessionFailureResponse
146
+ | UnrecognizedSessionResponse;
147
+
148
+ export type RedirectSessionPayload = {
149
+ redirectURL: string;
150
+ };
151
+
152
+ /**
153
+ * Internal shape returned by `normalizeSessionResponse()` before `hasSession()` post-processing.
154
+ *
155
+ * It includes regular Session Service object responses and redirect responses used for full-page
156
+ * session refresh.
157
+ */
158
+ export type NormalizedSessionPayload = SessionObjectResponse | RedirectSessionPayload;
159
+
160
+ /**
161
+ * Public response union returned from {@link Account#hasSession}.
162
+ *
163
+ * @group Session
164
+ */
165
+ export type SessionResponse =
166
+ | SessionSuccessResponse
167
+ | SessionFailureResponse
168
+ | UnrecognizedSessionResponse
169
+ | RedirectSessionResponse;
@@ -2,20 +2,16 @@
2
2
  * See LICENSE.md in the project root.
3
3
  */
4
4
 
5
- 'use strict'
6
-
7
- import { assert, isNonEmptyString, isUrl, isNonEmptyObj } from './validate.js';
5
+ import { assert, isNonEmptyObj, isNonEmptyString, isUrl } from './validate.js';
8
6
 
9
7
  /**
10
8
  * A simple utility function that allows looking up URLs from a dictionary
11
- * @memberof core
12
- * @param {string} url - A url like http://example.com, or a key used for lookup
13
- * @param {object<string,string>} urlMap - A map of URLs like
14
- * `{ DEV: 'http://dev.example.com' }`
15
- * @throws {SDKError} - If the url is not an string or is an empty string
16
- * @return {string} The url that points to the server
9
+ * @param url - A url like http://example.com, or a key used for lookup
10
+ * @param urlMap - A map of URLs like `{ DEV: 'http://dev.example.com' }`
11
+ * @returns The resolved URL: the mapped value when `url` is a known key, otherwise `url` itself
12
+ * @throws {SDKError} - If the url is not a string or is an empty string
17
13
  */
18
- export function urlMapper(url, urlMap) {
14
+ export function urlMapper(url: string, urlMap: Record<string, string>): string {
19
15
  assert(isNonEmptyString(url), `"url" param must be a non empty string: ${typeof url}`);
20
16
  if (isNonEmptyObj(urlMap) && isUrl(urlMap[url])) {
21
17
  return urlMap[url];