From 6172be6181fa80b31ed049ae79bf08c91bd9fb56 Mon Sep 17 00:00:00 2001 From: Babette Wagner Date: Tue, 17 Sep 2024 10:50:43 +0200 Subject: [PATCH] feat PA-4740: add ensureUserHasOptin --- dist/ps-web-apis.cjs.js | 12 +- dist/ps-web-apis.d.ts | 66 ++++++++ dist/ps-web-apis.esm.js | 8 +- src/ps-web-apis.ts | 337 ++++++++++++++++++++-------------------- 4 files changed, 255 insertions(+), 168 deletions(-) diff --git a/dist/ps-web-apis.cjs.js b/dist/ps-web-apis.cjs.js index d9ae370..b6e9d5a 100644 --- a/dist/ps-web-apis.cjs.js +++ b/dist/ps-web-apis.cjs.js @@ -78,6 +78,12 @@ function whoamiV1() { function utilsV1() { return requirePackage("utils:v1"); } +function waitingRoomV1() { + return requireApi("waiting_room:v1"); +} +function abV1() { + return requirePackage("ab:v1"); +} function CligV1() { return requirePackage("ppclig:v1"); } @@ -87,9 +93,11 @@ function CligV2() { var provideApi = provide; var requireApi = requirePackage; +exports.whoamiV1 = whoamiV1; +exports.utilsV1 = utilsV1; +exports.waitingRoomV1 = waitingRoomV1; +exports.abV1 = abV1; exports.CligV1 = CligV1; exports.CligV2 = CligV2; exports.provideApi = provideApi; exports.requireApi = requireApi; -exports.utilsV1 = utilsV1; -exports.whoamiV1 = whoamiV1; diff --git a/dist/ps-web-apis.d.ts b/dist/ps-web-apis.d.ts index ddd9530..a70b9bc 100644 --- a/dist/ps-web-apis.d.ts +++ b/dist/ps-web-apis.d.ts @@ -8,13 +8,22 @@ export interface WhoamiUserInfo { export interface PurchaseData { entitlements: [string]; } +export interface UserDataRequestResult { + success: boolean; + reason?: "userNotLoggedIn" | "generalError" | "userAborted"; +} export declare type FetchOptions = RequestInit & { timeout?: number; }; +export declare type WaitingRoomQueueDefault = ""; +export declare type WaitingRoomQueue = WaitingRoomQueueDefault | "auth" | "checkout"; /** * Custom fetch interface which includes the possibility to customize timeouts for fetch requests */ export declare type Fetch = (input: RequestInfo, init?: FetchOptions) => Promise; +export declare type GetRosettaEnvByKey = (key: string) => string | undefined; +export declare type WaitForCapacity = (queue: WaitingRoomQueue) => Promise; +export declare type RegisterIframeMessageListener = (eventtype: string, listener: (event: any, iframe: HTMLIFrameElement) => void) => void; export interface WhoamiV1 { /** * will assert valid not outdated session before fetch will be done. backend credentials will be added automatically @@ -31,13 +40,51 @@ export interface WhoamiV1 { * gives information if the user is currently a C1 User. These are users which are not logged in from * sso/mypass perspective. These users are originated from the apps and have potentially in app purchases. * If this method resolves to true isLogged in will resolve to false. + * @deprecated there is not replacement for the client planned */ isC1User(): boolean; + /** + * gives information if the user is currently a Plenigo User. These are users which are not logged in from + * sso/mypass perspective. These users are originated from the apps and have potentially in app purchases. + * If this method resolves to true isLogged in will resolve to false. + */ + isPlenigoUser(): boolean; /** * will assert valid not outdated session before promise is resolved * an error is resolved if session is invalid and not refeshable (= user logged out) */ ensureUserHasAuthorization(): Promise; + /** + * Ensures that the user has provided both a first name and a last name. + * If the user has not provided these details, the function will prompt the user + * to enter them. Depending on the `skippable` parameter, the user may be allowed + * to skip this step. + * + * @param skippable - If true, the user can choose to skip providing their first name + * and last name. + * @param title - Optional. A custom title for the prompt that asks for the user's + * first name and last name. If not set default will be used. + * @param text - Optional. A custom text or message to display in the prompt. If not + * set default will be used. + * + * @returns A promise that resolves to an object indicating whether the user provided + * the required information (`success: true`) or not, along with a `reason` if applicable. + * Possible reasons include "userNotLoggedIn", "error", or "userAborted". + */ + ensureUserHasFirstNameAndLastName(skippable: boolean, title?: string, text?: string): Promise; + /** + * Ensures that the user has opted in to a specific data collection or processing activity. + * If the user has not opted in, the function will prompt the user to do so. + * + * @param optIn - A string representing the specific opt-in name. + * This could be the new Marketing_AS_2024 or any other opt-in, + * which are present in agreement. + * + * @returns A promise that resolves to an object indicating whether the user opted in + * successfully (`success: true`) or not, along with a `reason` if applicable. + * Possible reasons include "userNotLoggedIn", "generalError", or "userAborted". + */ + ensureUserHasOptin(optIn: string): Promise; /** * will start login-process (e.g. go to sso-login) */ @@ -66,12 +113,18 @@ export interface WhoamiV1 { /** * will request customer pseudo id for currently logged user from consent backend * @param clientId The string identifier of the client for which the customer id is requested. + * @deprecated there is not replacement for the client planned */ getCustomerId(clientId: string): Promise; /** * will provide unsafe purchase data */ getUnsafePurchaseData(): Promise; + /** + * will provide users registration date if available otherwise returns null. + * Registration date in unix timestamp. + */ + getUnsafeRegistrationDate(): Promise; /** * will provide jaId for logged in users, otherwise * @throws error @@ -80,6 +133,17 @@ export interface WhoamiV1 { } export interface UtilsV1 { fetchWithTimeout: Fetch; + getRosettaEnvByKey: GetRosettaEnvByKey; + registerIframeMessageListener: RegisterIframeMessageListener; +} +export interface AbV1 { + userInTestGroupForFeature: (key: string) => { + canSeeFeature: boolean; + testGroup: "A" | "B"; + }; +} +export interface WaitingRoomV1 { + waitForCapacity: WaitForCapacity; } export declare type ILayer = "privacy" | "reject"; export declare type IApp = "offerpage" | "checkout" | "cancellation"; @@ -110,6 +174,8 @@ export declare type ICligV2 = (app: IApp) => Promise<{ }>; export declare function whoamiV1(): Promise; export declare function utilsV1(): Promise; +export declare function waitingRoomV1(): Promise; +export declare function abV1(): Promise; export declare function CligV1(): Promise; export declare function CligV2(): Promise; export declare const provideApi: typeof provide; diff --git a/dist/ps-web-apis.esm.js b/dist/ps-web-apis.esm.js index 7ac480d..f402997 100644 --- a/dist/ps-web-apis.esm.js +++ b/dist/ps-web-apis.esm.js @@ -74,6 +74,12 @@ function whoamiV1() { function utilsV1() { return requirePackage("utils:v1"); } +function waitingRoomV1() { + return requireApi("waiting_room:v1"); +} +function abV1() { + return requirePackage("ab:v1"); +} function CligV1() { return requirePackage("ppclig:v1"); } @@ -83,4 +89,4 @@ function CligV2() { var provideApi = provide; var requireApi = requirePackage; -export { CligV1, CligV2, provideApi, requireApi, utilsV1, whoamiV1 }; +export { whoamiV1, utilsV1, waitingRoomV1, abV1, CligV1, CligV2, provideApi, requireApi }; diff --git a/src/ps-web-apis.ts b/src/ps-web-apis.ts index 230ddd5..53b436b 100644 --- a/src/ps-web-apis.ts +++ b/src/ps-web-apis.ts @@ -1,59 +1,58 @@ import { provide } from "./apiprovide"; function requirePackage(name: string): Promise { - // -- START -- static loader - const unresolvedPackages = {} as any; - const providedPackages = {} as any; - const loaderName = "pssmasloader"; - // set or reuse existing loader implementation - const loader = ((window as any)[loaderName] = (window as any)[loaderName] || { - // Requires packageName and returns it via callback - require(packageName: string, cb: any) { - const pack = providedPackages[packageName]; - if (pack !== undefined) { - // -- will callback directly if required functionality was already provided - cb(pack, null); - } else { - // -- will queue callbacks if required functionality is not yet available - unresolvedPackages[packageName] = unresolvedPackages[packageName] || []; - unresolvedPackages[packageName].push(cb); - } - }, - - // private state - _: { - u: unresolvedPackages, - p: providedPackages, - }, - }); - // -- END -- static loader - - return new Promise((resolve, reject) => { - loader.require(name, (res: T, error: any) => { - if (error) { - reject(error); - } else { - resolve(res); - } + // -- START -- static loader + const unresolvedPackages = {} as any; + const providedPackages = {} as any; + const loaderName = "pssmasloader"; + // set or reuse existing loader implementation + const loader = ((window as any)[loaderName] = (window as any)[loaderName] || { + // Requires packageName and returns it via callback + require(packageName: string, cb: any) { + const pack = providedPackages[packageName]; + if (pack !== undefined) { + // -- will callback directly if required functionality was already provided + cb(pack, null); + } else { + // -- will queue callbacks if required functionality is not yet available + unresolvedPackages[packageName] = unresolvedPackages[packageName] || []; + unresolvedPackages[packageName].push(cb); + } + }, + + // private state + _: { + u: unresolvedPackages, + p: providedPackages + } + }); + // -- END -- static loader + + return new Promise((resolve, reject) => { + loader.require(name, (res: T, error: any) => { + if (error) { + reject(error); + } else { + resolve(res); + } + }); }); - }); } export interface WhoamiUserInfo { - user_id: string; - first_name?: string; - last_name?: string; + user_id: string; + first_name?: string; + last_name?: string; } export interface PurchaseData { - entitlements: [string]; + entitlements: [string]; } export interface UserDataRequestResult { - success: boolean; - reason?: "userNotLoggedIn" | "generalError" | "userAborted"; + success: boolean; + reason?: "userNotLoggedIn" | "generalError" | "userAborted"; } - export type FetchOptions = RequestInit & { timeout?: number }; export type WaitingRoomQueueDefault = ""; export type WaitingRoomQueue = WaitingRoomQueueDefault | "auth" | "checkout"; @@ -61,126 +60,134 @@ export type WaitingRoomQueue = WaitingRoomQueueDefault | "auth" | "checkout"; /** * Custom fetch interface which includes the possibility to customize timeouts for fetch requests */ -export type Fetch = ( - input: RequestInfo, - init?: FetchOptions -) => Promise; +export type Fetch = (input: RequestInfo, init?: FetchOptions) => Promise; export type GetRosettaEnvByKey = (key: string) => string | undefined; export type WaitForCapacity = (queue: WaitingRoomQueue) => Promise; export type RegisterIframeMessageListener = (eventtype: string, listener: (event: any, iframe: HTMLIFrameElement) => void) => void; - - export interface WhoamiV1 { - /** - * will assert valid not outdated session before fetch will be done. backend credentials will be added automatically - * an error is resolved if session is invalid and not refeshable (= user logged out) - * Important: as of version 1.9.9 all requests are timeout after 5s by default. - * Can be changed by adding the field timeout to the FetchOptions Interface - */ - authorizedFetch: Fetch; - /** - * gives information if user is currently loggedin from ui perspective - */ - isLoggedIn(): boolean; - /** - * gives information if the user is currently a C1 User. These are users which are not logged in from - * sso/mypass perspective. These users are originated from the apps and have potentially in app purchases. - * If this method resolves to true isLogged in will resolve to false. - * @deprecated there is not replacement for the client planned - */ - isC1User(): boolean; - /** - * gives information if the user is currently a Plenigo User. These are users which are not logged in from - * sso/mypass perspective. These users are originated from the apps and have potentially in app purchases. - * If this method resolves to true isLogged in will resolve to false. - */ - isPlenigoUser(): boolean; - /** - * will assert valid not outdated session before promise is resolved - * an error is resolved if session is invalid and not refeshable (= user logged out) - */ - ensureUserHasAuthorization(): Promise; - - /** - * Ensures that the user has provided both a first name and a last name. - * If the user has not provided these details, the function will prompt the user - * to enter them. Depending on the `skippable` parameter, the user may be allowed - * to skip this step. - * - * @param skippable - If true, the user can choose to skip providing their first name - * and last name. - * @param title - Optional. A custom title for the prompt that asks for the user's - * first name and last name. If not set default will be used. - * @param text - Optional. A custom text or message to display in the prompt. If not - * set default will be used. - * - * @returns A promise that resolves to an object indicating whether the user provided - * the required information (`success: true`) or not, along with a `reason` if applicable. - * Possible reasons include "userNotLoggedIn", "error", or "userAborted". - */ - ensureUserHasFirstNameAndLastName(skippable: boolean, title?: string, text?: string): Promise; - - /** - * will start login-process (e.g. go to sso-login) - */ - doLogin(additionalParameter?: Map): void; - /** - * will start registration-process (e.g. go to sso-register) - */ - doRegister(additionalParameter?: Map): void; - /** - * will start logout-process (e.g. go to sso-logout) - */ - doLogout(additionalParameter?: Map): void; - /** - * will start logout-process and redirect user to portal homepage afterwards (e.g. go to sso-logout) - */ - doLogoutToHome(additionalParameter?: Map): void; - /** - * will update access token and therefore content entitlements to current state - */ - forceAccessTokenRefresh(): Promise; - /** - * will request userinfo from whoami backend - * @return {WhoamiUserInfo} some relevant userdata - */ - getUserInfo(): Promise; - /** - * will request customer pseudo id for currently logged user from consent backend - * @param clientId The string identifier of the client for which the customer id is requested. - * @deprecated there is not replacement for the client planned - */ - getCustomerId(clientId: string): Promise; - /** - * will provide unsafe purchase data - */ - getUnsafePurchaseData(): Promise; - /** - * will provide users registration date if available otherwise returns null. - * Registration date in unix timestamp. - */ - getUnsafeRegistrationDate(): Promise; - - /** - * will provide jaId for logged in users, otherwise - * @throws error - */ - getJaId(): string; + /** + * will assert valid not outdated session before fetch will be done. backend credentials will be added automatically + * an error is resolved if session is invalid and not refeshable (= user logged out) + * Important: as of version 1.9.9 all requests are timeout after 5s by default. + * Can be changed by adding the field timeout to the FetchOptions Interface + */ + authorizedFetch: Fetch; + /** + * gives information if user is currently loggedin from ui perspective + */ + isLoggedIn(): boolean; + /** + * gives information if the user is currently a C1 User. These are users which are not logged in from + * sso/mypass perspective. These users are originated from the apps and have potentially in app purchases. + * If this method resolves to true isLogged in will resolve to false. + * @deprecated there is not replacement for the client planned + */ + isC1User(): boolean; + /** + * gives information if the user is currently a Plenigo User. These are users which are not logged in from + * sso/mypass perspective. These users are originated from the apps and have potentially in app purchases. + * If this method resolves to true isLogged in will resolve to false. + */ + isPlenigoUser(): boolean; + /** + * will assert valid not outdated session before promise is resolved + * an error is resolved if session is invalid and not refeshable (= user logged out) + */ + ensureUserHasAuthorization(): Promise; + + /** + * Ensures that the user has provided both a first name and a last name. + * If the user has not provided these details, the function will prompt the user + * to enter them. Depending on the `skippable` parameter, the user may be allowed + * to skip this step. + * + * @param skippable - If true, the user can choose to skip providing their first name + * and last name. + * @param title - Optional. A custom title for the prompt that asks for the user's + * first name and last name. If not set default will be used. + * @param text - Optional. A custom text or message to display in the prompt. If not + * set default will be used. + * + * @returns A promise that resolves to an object indicating whether the user provided + * the required information (`success: true`) or not, along with a `reason` if applicable. + * Possible reasons include "userNotLoggedIn", "error", or "userAborted". + */ + ensureUserHasFirstNameAndLastName(skippable: boolean, title?: string, text?: string): Promise; + + /** + * Ensures that the user has opted in to a specific data collection or processing activity. + * If the user has not opted in, the function will prompt the user to do so. + * + * @param optIn - A string representing the specific opt-in name. + * This could be the new Marketing_AS_2024 or any other opt-in, + * which are present in agreement. + * + * @returns A promise that resolves to an object indicating whether the user opted in + * successfully (`success: true`) or not, along with a `reason` if applicable. + * Possible reasons include "userNotLoggedIn", "generalError", or "userAborted". + */ + ensureUserHasOptin(optIn: string): Promise; + /** + * will start login-process (e.g. go to sso-login) + */ + doLogin(additionalParameter?: Map): void; + /** + * will start registration-process (e.g. go to sso-register) + */ + doRegister(additionalParameter?: Map): void; + /** + * will start logout-process (e.g. go to sso-logout) + */ + doLogout(additionalParameter?: Map): void; + /** + * will start logout-process and redirect user to portal homepage afterwards (e.g. go to sso-logout) + */ + doLogoutToHome(additionalParameter?: Map): void; + /** + * will update access token and therefore content entitlements to current state + */ + forceAccessTokenRefresh(): Promise; + /** + * will request userinfo from whoami backend + * @return {WhoamiUserInfo} some relevant userdata + */ + getUserInfo(): Promise; + /** + * will request customer pseudo id for currently logged user from consent backend + * @param clientId The string identifier of the client for which the customer id is requested. + * @deprecated there is not replacement for the client planned + */ + getCustomerId(clientId: string): Promise; + /** + * will provide unsafe purchase data + */ + getUnsafePurchaseData(): Promise; + /** + * will provide users registration date if available otherwise returns null. + * Registration date in unix timestamp. + */ + getUnsafeRegistrationDate(): Promise; + + /** + * will provide jaId for logged in users, otherwise + * @throws error + */ + getJaId(): string; } export interface UtilsV1 { - fetchWithTimeout: Fetch; - getRosettaEnvByKey: GetRosettaEnvByKey; - registerIframeMessageListener: RegisterIframeMessageListener; + fetchWithTimeout: Fetch; + getRosettaEnvByKey: GetRosettaEnvByKey; + registerIframeMessageListener: RegisterIframeMessageListener; } export interface AbV1 { - userInTestGroupForFeature: (key: string) => { canSeeFeature: boolean, testGroup: "A" | "B" }; + userInTestGroupForFeature: (key: string) => { canSeeFeature: boolean; testGroup: "A" | "B" }; } export interface WaitingRoomV1 { - waitForCapacity: WaitForCapacity; + waitForCapacity: WaitForCapacity; } export type ILayer = "privacy" | "reject"; @@ -188,51 +195,51 @@ export type IApp = "offerpage" | "checkout" | "cancellation"; export type ITenant = "welt" | "bild"; export interface IAccount { - accountId: number | string; - propertyId: number | string; - baseEndpoint: string; - purEntitlement: string; - layers: { - [key in ILayer]: number | string; - }; + accountId: number | string; + propertyId: number | string; + baseEndpoint: string; + purEntitlement: string; + layers: { + [key in ILayer]: number | string; + }; } export type IAppConfig = { - [key in ITenant]: IAccount; + [key in ITenant]: IAccount; } & { urlsWithoutConsentLayer: string[] }; export type IConfig = { - [key in IApp]: IAppConfig; + [key in IApp]: IAppConfig; }; export interface ICligV1 { - init: (app: IApp) => Promise; - open: (layer: ILayer) => void; + init: (app: IApp) => Promise; + open: (layer: ILayer) => void; } export type ICligV2 = (app: IApp) => Promise<{ open: (layer: ILayer) => void }>; export function whoamiV1(): Promise { - return requirePackage("whoami:v1"); + return requirePackage("whoami:v1"); } export function utilsV1(): Promise { - return requirePackage("utils:v1"); + return requirePackage("utils:v1"); } export function waitingRoomV1(): Promise { - return requireApi("waiting_room:v1"); + return requireApi("waiting_room:v1"); } export function abV1(): Promise { - return requirePackage("ab:v1"); + return requirePackage("ab:v1"); } export function CligV1(): Promise { - return requirePackage("ppclig:v1"); + return requirePackage("ppclig:v1"); } export function CligV2(): Promise { - return requirePackage("clig:v2"); + return requirePackage("clig:v2"); } export const provideApi = provide;