UNPKG

@open-condo/miniapp-utils

Version:

A set of helper functions / components / hooks used to build new condo apps fast

148 lines (143 loc) 4.85 kB
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); // src/helpers/sender.ts import { getCookie as getCookie2, setCookie as setCookie2 } from "cookies-next"; // src/helpers/embeddingContext.tsx import { deleteCookie, getCookie, setCookie } from "cookies-next"; import React, { useEffect, useMemo, useState, createContext, useContext } from "react"; import { z } from "zod"; // src/helpers/uuid.ts function generateUUIDv4() { const webCrypto = typeof globalThis !== "undefined" ? globalThis.crypto : void 0; if (webCrypto && typeof webCrypto.randomUUID === "function") { return webCrypto.randomUUID(); } let randomValues; if (webCrypto && typeof webCrypto.getRandomValues === "function") { randomValues = new Uint8Array(16); webCrypto.getRandomValues(randomValues); } else { try { const { randomBytes } = __require("crypto"); randomValues = randomBytes(16); } catch { throw new Error("No secure random source available in this environment"); } } randomValues[6] = randomValues[6] & 15 | 64; randomValues[8] = randomValues[8] & 63 | 128; return [...randomValues].map((value, index) => { const hex = value.toString(16).padStart(2, "0"); if (index === 4 || index === 6 || index === 8 || index === 10) { return `-${hex}`; } return hex; }).join(""); } // src/helpers/embeddingContext.tsx var EMBEDDING_CONTEXT_COOKIE_NAME = "embeddingContext"; var EMBEDDING_CONTEXT_QUERY_PARAM = "embeddingContext"; var EMBEDDING_CONTEXT_SCHEMA = z.strictObject({ dv: z.literal(1), app: z.strictObject({ id: z.string(), version: z.string().optional(), build: z.string().optional() }), platform: z.enum(["iOS", "Android", "web"]), os: z.strictObject({ name: z.string(), version: z.string().optional() }).optional(), device: z.strictObject({ id: z.string() }) }); var EMBEDDING_CONTEXT_WITH_SOURCE_SCHEMA = z.strictObject({ ctx: EMBEDDING_CONTEXT_SCHEMA, source: z.enum(["query", "cookie"]) }); var IS_PRIMARY_ALIVE_MESSAGE_SCHEMA = z.object({ type: z.literal("EmbeddingContextPrimaryPolling"), data: z.strictObject({ requestId: z.string() }) }); var IS_PRIMARY_ALIVE_RESPONSE_SCHEMA = z.object({ type: z.literal("EmbeddingContextPrimaryPollingResult"), data: z.strictObject({ requestId: z.string(), isPrimary: z.boolean() }) }); var ReactEmbeddingContext = createContext(null); function b64toContext(b64) { try { const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)); const decodedUTFString = new TextDecoder().decode(bytes); const parsedCtx = JSON.parse(decodedUTFString); return EMBEDDING_CONTEXT_SCHEMA.parse(parsedCtx); } catch { return null; } } function getEmbeddingContext(req, res) { try { const queryParamValue = req ? new URL(req.url ?? "/", "https://_").searchParams.get(EMBEDDING_CONTEXT_QUERY_PARAM) : new URLSearchParams(window.location.search).get(EMBEDDING_CONTEXT_QUERY_PARAM); if (queryParamValue) { const ctx = b64toContext(decodeURIComponent(queryParamValue)); if (ctx) return { ctx, source: "query" }; } } catch { } const cookieValue = getCookie(EMBEDDING_CONTEXT_COOKIE_NAME, { req, res }); if (cookieValue) { const ctx = b64toContext(cookieValue); if (ctx) return { ctx, source: "cookie" }; } return null; } // src/helpers/sender.ts var FINGERPRINT_ID_COOKIE_NAME = "fingerprint"; var FINGERPRINT_ID_LENGTH = 32; var VERY_LONG_MAX_AGE_IN_SECONDS = Math.pow(2, 31) - 1; function makeId(length) { const croppedLength = Math.min(length, 32); return generateUUIDv4().replaceAll("-", "").substring(0, croppedLength); } function generateFingerprint() { return makeId(FINGERPRINT_ID_LENGTH); } function getClientSideFingerprint() { const embeddingContext = getEmbeddingContext(); if (embeddingContext) { return embeddingContext.ctx.device.id; } let fingerprint = getCookie2(FINGERPRINT_ID_COOKIE_NAME); if (!fingerprint) { fingerprint = generateFingerprint(); } setCookie2(FINGERPRINT_ID_COOKIE_NAME, fingerprint, { maxAge: VERY_LONG_MAX_AGE_IN_SECONDS // no "maxAge" or "expires" means that cookie clears when session ends (f.e. when browser closes) }); return fingerprint; } function getClientSideSenderInfo() { return { dv: 1, fingerprint: getClientSideFingerprint() }; } export { FINGERPRINT_ID_COOKIE_NAME, FINGERPRINT_ID_LENGTH, generateFingerprint, getClientSideFingerprint, getClientSideSenderInfo }; //# sourceMappingURL=sender.mjs.map