@snap/camera-kit
Version:
Camera Kit Web
100 lines • 5.65 kB
JavaScript
import { defineAction, defineActions, defineState, defineStates, dispatch, forActions, inStates, StateMachine, } from "@snap/state-management";
import { catchError, forkJoin, from, map, merge, of, switchMap } from "rxjs";
import { Injectable } from "@snap/ts-inject";
import { LegalDocument, LegalDocument_Type, LegalPrompt as LegalPromptProto, } from "../generated-proto/pb_schema/camera_kit/v3/legal_prompt";
import { getLogger } from "../logger/logger";
import { ExpiringPersistence } from "../persistence/ExpiringPersistence";
import { IndexedDBPersistence } from "../persistence/IndexedDBPersistence";
import { remoteConfigurationFactory } from "../remote-configuration/remoteConfiguration";
import { GetInitializationConfigResponse } from "../generated-proto/pb_schema/camera_kit/v3/service";
import { legalPromptFactory } from "./legalPrompt";
const logger = getLogger("LegalState");
const tosContentHashExpiry = 12 * 60 * 60;
const tosContentHashKey = "lastAcceptedTosContentHash";
const createLegalState = () => {
const states = defineStates(defineState("unknown")(), defineState("accepted")(), defineState("rejected")());
const actions = defineActions(defineAction("requestLegalPrompt")(), defineAction("accept")(), defineAction("reject")());
return new StateMachine(actions, states, states.unknown(), (actions) => {
return merge(actions.pipe(inStates("unknown"), forActions("accept"), map(() => states.accepted())), actions.pipe(inStates("unknown"), forActions("reject"), map(() => states.rejected())), actions.pipe(inStates("rejected"), forActions("requestLegalPrompt"), map(() => states.unknown())));
});
};
const defaultLegalDocumentDate = new Date("2021-09-30T00:00:00+00:00");
const defaultLegalPrompt = LegalPromptProto.fromPartial({
documents: [
LegalDocument.fromPartial({
type: LegalDocument_Type.PRIVACY_POLICY,
webUrl: "https://values.snap.com/privacy/privacy-policy",
version: "1",
timestamp: defaultLegalDocumentDate,
}),
LegalDocument.fromPartial({
type: LegalDocument_Type.TERMS_OF_SERVICE,
webUrl: "https://snap.com/terms",
version: "1",
timestamp: defaultLegalDocumentDate,
}),
LegalDocument.fromPartial({
type: LegalDocument_Type.LEARN_MORE,
webUrl: "https://support.snapchat.com/article/camera-information-use",
version: "1",
timestamp: defaultLegalDocumentDate,
}),
],
disabled: true,
});
const defaultInitConfig = GetInitializationConfigResponse.fromPartial({});
const hasAnyValue = (c) => {
var _a, _b;
return ((_b = (_a = c.value) === null || _a === void 0 ? void 0 : _a.anyValue) === null || _b === void 0 ? void 0 : _b.value) instanceof Uint8Array;
};
const getDocumentOrDefault = (documents) => (type) => {
var _a;
return ((_a = documents.find((d) => d.type === type)) !== null && _a !== void 0 ? _a : defaultLegalPrompt.documents.find((d) => d.type === type));
};
export const legalStateFactory = Injectable("legalState", [remoteConfigurationFactory.token, legalPromptFactory.token], (remoteConfig, legalPrompt) => {
const persistance = new ExpiringPersistence(() => tosContentHashExpiry, new IndexedDBPersistence({ databaseName: "Legal" }));
const getLastAcceptedTosContentHash = () => from(persistance.retrieve(tosContentHashKey).catch((error) => logger.warn(error)));
const setLastAcceptedTosContentHash = (hash) => persistance.store(tosContentHashKey, hash).catch((error) => logger.warn(error));
const legalState = createLegalState();
legalState.events
.pipe(inStates("unknown"), forActions("requestLegalPrompt"), switchMap(() => forkJoin({
cofConfig: remoteConfig.get("CAMERA_KIT_LEGAL_PROMPT").pipe(map((configResults) => {
const config = configResults.find(hasAnyValue);
if (!config)
return defaultLegalPrompt;
return LegalPromptProto.decode(config.value.anyValue.value);
}), catchError((error) => {
logger.error(error);
return of(defaultLegalPrompt);
})),
initConfig: remoteConfig.getInitializationConfig().pipe(catchError((error) => {
logger.error(error);
return of(defaultInitConfig);
})),
})), switchMap(({ cofConfig, initConfig }) => {
var _a;
if ((_a = initConfig.legalPrompt) === null || _a === void 0 ? void 0 : _a.disabled) {
return of(legalState.actions.accept("disabled"));
}
if (cofConfig.disabled) {
return of(legalState.actions.accept("disabled"));
}
const documentOfType = getDocumentOrDefault(cofConfig.documents);
const prompt = legalPrompt(documentOfType(LegalDocument_Type.PRIVACY_POLICY), documentOfType(LegalDocument_Type.TERMS_OF_SERVICE), documentOfType(LegalDocument_Type.LEARN_MORE), initConfig.childrenProtectionActRestricted);
return getLastAcceptedTosContentHash().pipe(switchMap((lastAcceptedTosContentHash) => {
if (prompt.contentHash === lastAcceptedTosContentHash)
return of(true);
return prompt.show();
}), map((didAccept) => {
if (!didAccept)
return legalState.actions.reject(prompt.contentHash);
setLastAcceptedTosContentHash(prompt.contentHash);
return legalState.actions.accept(prompt.contentHash);
}));
}), dispatch(legalState))
.subscribe({
error: logger.error,
});
return legalState;
});
//# sourceMappingURL=legalState.js.map