@cuemath/leap 4.0.5-as1 → 4.0.5-as3

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.
@@ -0,0 +1,21 @@
1
+ const i = (e, c) => {
2
+ var n;
3
+ if (!e) return null;
4
+ try {
5
+ const t = e.includes(",") ? e.split(",")[1] : e, a = e.includes("data:") ? (n = e.split(";")[0]) == null ? void 0 : n.split(":")[1] : "image/png";
6
+ if (t) {
7
+ const l = atob(t), o = new Array(l.length);
8
+ for (let r = 0; r < l.length; r++)
9
+ o[r] = l.charCodeAt(r);
10
+ const s = new Uint8Array(o);
11
+ return new File([s], c, { type: a });
12
+ }
13
+ return null;
14
+ } catch (t) {
15
+ return console.error("Failed to convert base64 to file:", t), null;
16
+ }
17
+ };
18
+ export {
19
+ i as base64ToFile
20
+ };
21
+ //# sourceMappingURL=fraud-alert-modal-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fraud-alert-modal-helpers.js","sources":["../../../../src/features/fraud-detection/fraud-alert-modal/fraud-alert-modal-helpers.ts"],"sourcesContent":["/**\n * Converts a base64 image string to a File object\n * @param base64String - Base64 encoded image string (with or without data URI prefix)\n * @param fileName - Name for the generated file\n * @returns File object or null if conversion fails\n */\nexport const base64ToFile = (base64String: string | null, fileName: string): File | null => {\n if (!base64String) return null;\n\n try {\n const base64Data = base64String.includes(',') ? base64String.split(',')[1] : base64String;\n\n const mimeType = base64String.includes('data:')\n ? base64String.split(';')[0]?.split(':')[1]\n : 'image/png';\n\n if (base64Data) {\n const byteCharacters = atob(base64Data);\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n\n // Create File directly from byte array\n return new File([byteArray], fileName, { type: mimeType });\n }\n\n return null;\n } catch (error) {\n console.error('Failed to convert base64 to file:', error);\n\n return null;\n }\n};\n"],"names":["base64ToFile","base64String","fileName","_a","base64Data","mimeType","byteCharacters","byteNumbers","i","byteArray","error"],"mappings":"AAMa,MAAAA,IAAe,CAACC,GAA6BC,MAAkC;AAA/E,MAAAC;AACP,MAAA,CAACF,EAAqB,QAAA;AAEtB,MAAA;AACI,UAAAG,IAAaH,EAAa,SAAS,GAAG,IAAIA,EAAa,MAAM,GAAG,EAAE,CAAC,IAAIA,GAEvEI,IAAWJ,EAAa,SAAS,OAAO,KAC1CE,IAAAF,EAAa,MAAM,GAAG,EAAE,CAAC,MAAzB,gBAAAE,EAA4B,MAAM,KAAK,KACvC;AAEJ,QAAIC,GAAY;AACR,YAAAE,IAAiB,KAAKF,CAAU,GAChCG,IAAc,IAAI,MAAMD,EAAe,MAAM;AAEnD,eAASE,IAAI,GAAGA,IAAIF,EAAe,QAAQE;AACzC,QAAAD,EAAYC,CAAC,IAAIF,EAAe,WAAWE,CAAC;AAGxC,YAAAC,IAAY,IAAI,WAAWF,CAAW;AAGrC,aAAA,IAAI,KAAK,CAACE,CAAS,GAAGP,GAAU,EAAE,MAAMG,EAAA,CAAU;AAAA,IAC3D;AAEO,WAAA;AAAA,WACAK,GAAO;AACN,mBAAA,MAAM,qCAAqCA,CAAK,GAEjD;AAAA,EACT;AACF;"}
@@ -1,24 +1,41 @@
1
- import { jsxs as d, jsx as e } from "react/jsx-runtime";
2
- import { memo as c, useState as u, useCallback as h, useEffect as m } from "react";
3
- import { ILLUSTRATIONS as $ } from "../../../assets/illustrations/illustrations.js";
4
- import g from "../../ui/modals/use-modal-actions.js";
5
- import r from "../../ui/text/text.js";
6
- import f from "../../ui/image/image.js";
7
- import o from "../../ui/layout/flex-view.js";
8
- import p from "../../ui/buttons/button/button.js";
9
- import n from "../../ui/separator/separator.js";
10
- const A = c(function() {
11
- const { closeModal: i } = g(), [L, l] = u(10), t = h(() => {
12
- i();
13
- }, [i]);
14
- return m(() => {
15
- const s = setInterval(() => {
16
- l((a) => a <= 1 ? (t(), 0) : a - 1);
17
- }, 1e5);
18
- return () => clearInterval(s);
19
- }, [t]), /* @__PURE__ */ d(o, { $gapX: 1.5, $gutterX: 1.5, $background: "RED_1", children: [
1
+ import { jsxs as g, jsx as e } from "react/jsx-runtime";
2
+ import { memo as b, useCallback as I, useEffect as L } from "react";
3
+ import { useLocalPeer as y, useRemotePeers as C, useCaptureMediaStreamImage as F } from "@cuemath/av";
4
+ import { ILLUSTRATIONS as R } from "../../../assets/illustrations/illustrations.js";
5
+ import X from "../../ui/modals/use-modal-actions.js";
6
+ import o from "../../ui/text/text.js";
7
+ import _ from "../../ui/image/image.js";
8
+ import d from "../../ui/layout/flex-view.js";
9
+ import w from "../../ui/buttons/button/button.js";
10
+ import s from "../../ui/separator/separator.js";
11
+ import E from "../../ui/modals/use-modal-params.js";
12
+ import M from "../../worksheet/worksheet/hooks/use-s3-helper.js";
13
+ import { base64ToFile as f } from "./fraud-alert-modal-helpers.js";
14
+ const B = { type: "fraud-login" }, D = b(function() {
15
+ const { closeModal: u } = X(), { teacherId: $, studentId: i, handleLogout: c } = E(), p = I(() => {
16
+ u(), c();
17
+ }, [u, c]), t = y(), r = C().find((a) => a.userId === $), n = F(), l = M({
18
+ studentId: i,
19
+ query: B
20
+ });
21
+ return L(() => {
22
+ if (!(r != null && r.id) || !(t != null && t.id))
23
+ return;
24
+ const { image: a } = n(r == null ? void 0 : r.id, "camera"), { image: A } = n(t == null ? void 0 : t.id, "camera"), m = f(a, `teacher-${Date.now()}.png`), h = f(A, `student-${Date.now()}.png`);
25
+ if (!m || !h) {
26
+ console.error("Failed to convert images to files");
27
+ return;
28
+ }
29
+ l({
30
+ fileKey: `media/fraud-login/${i}/`,
31
+ images: [
32
+ { file: m, url: "teacher" },
33
+ { file: h, url: "student" }
34
+ ]
35
+ });
36
+ }, [n, t == null ? void 0 : t.id, r == null ? void 0 : r.id, i, l]), /* @__PURE__ */ g(d, { $gapX: 1.5, $gutterX: 1.5, $background: "RED_1", children: [
20
37
  /* @__PURE__ */ e(
21
- o,
38
+ d,
22
39
  {
23
40
  $justifyContent: "center",
24
41
  $alignItems: "center",
@@ -27,7 +44,7 @@ const A = c(function() {
27
44
  $widthX: 4.5,
28
45
  $background: "RED_2",
29
46
  children: /* @__PURE__ */ e(
30
- o,
47
+ d,
31
48
  {
32
49
  $justifyContent: "center",
33
50
  $alignItems: "center",
@@ -35,44 +52,44 @@ const A = c(function() {
35
52
  $heightX: 3.5,
36
53
  $widthX: 3.5,
37
54
  $background: "RED_4",
38
- children: /* @__PURE__ */ e(f, { src: $.ALERT_BULB, alt: "Fraud Alert", height: 40, width: 40 })
55
+ children: /* @__PURE__ */ e(_, { src: R.ALERT_BULB, alt: "Fraud Alert", height: 40, width: 40 })
39
56
  }
40
57
  )
41
58
  }
42
59
  ),
43
- /* @__PURE__ */ e(n, { heightX: 2 }),
44
- /* @__PURE__ */ e(r, { $renderAs: "ah4-bold", $color: "RED_6", children: "Fraudulent Login Detected!" }),
45
- /* @__PURE__ */ e(n, { height: 12 }),
46
- /* @__PURE__ */ d(r, { $renderAs: "ub2", color: "BLACK_1", children: [
60
+ /* @__PURE__ */ e(s, { heightX: 2 }),
61
+ /* @__PURE__ */ e(o, { $renderAs: "ah4-bold", $color: "RED_6", children: "Fraudulent Login Detected!" }),
62
+ /* @__PURE__ */ e(s, { height: 12 }),
63
+ /* @__PURE__ */ g(o, { $renderAs: "ub2", color: "BLACK_1", children: [
47
64
  "You have logged into a student's LEAP account, which is strictly prohibited. This is considered",
48
65
  " ",
49
- /* @__PURE__ */ e(r, { as: "span", $renderAs: "ub2-bold", color: "BLACK_1", $inline: !0, children: "fraudulent activity" }),
66
+ /* @__PURE__ */ e(o, { as: "span", $renderAs: "ub2-bold", color: "BLACK_1", $inline: !0, children: "fraudulent activity" }),
50
67
  " ",
51
68
  "and may result in strict action, including a",
52
69
  " ",
53
- /* @__PURE__ */ e(r, { as: "span", $renderAs: "ub2-bold", color: "BLACK_1", $inline: !0, children: "heavy penalty" }),
70
+ /* @__PURE__ */ e(o, { as: "span", $renderAs: "ub2-bold", color: "BLACK_1", $inline: !0, children: "heavy penalty" }),
54
71
  " ",
55
72
  "or",
56
73
  " ",
57
- /* @__PURE__ */ e(r, { as: "span", $renderAs: "ub2-bold", color: "BLACK_1", $inline: !0, children: "discontinuation" }),
74
+ /* @__PURE__ */ e(o, { as: "span", $renderAs: "ub2-bold", color: "BLACK_1", $inline: !0, children: "discontinuation" }),
58
75
  " ",
59
76
  "from conducting Cuemath classes."
60
77
  ] }),
61
- /* @__PURE__ */ e(n, { heightX: 2 }),
78
+ /* @__PURE__ */ e(s, { heightX: 2 }),
62
79
  /* @__PURE__ */ e(
63
- p,
80
+ w,
64
81
  {
65
82
  renderAs: "primary",
66
83
  alignSelf: "flex-end",
67
84
  shape: "square",
68
- onClick: t,
85
+ onClick: p,
69
86
  label: "Log out",
70
87
  width: "50%"
71
88
  }
72
89
  )
73
90
  ] });
74
- }), x = A;
91
+ }), V = D;
75
92
  export {
76
- x as default
93
+ V as default
77
94
  };
78
95
  //# sourceMappingURL=fraud-alert-modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fraud-alert-modal.js","sources":["../../../../src/features/fraud-detection/fraud-alert-modal/fraud-alert-modal.tsx"],"sourcesContent":["/**\n * Fraud Alert Modal Component\n * Displays fraud detection details and auto-logout countdown\n */\n\nimport { memo, useCallback, useEffect, useState, type FC } from 'react';\n\nimport { ILLUSTRATIONS } from '../../../assets/illustrations/illustrations';\nimport useModalActions from '../../ui/modals/use-modal-actions';\nimport Text from '../../ui/text/text';\nimport Image from '../../ui/image/image';\nimport FlexView from '../../ui/layout/flex-view';\nimport Button from '../../ui/buttons/button/button';\nimport Separator from '../../ui/separator/separator';\n\nconst FraudAlertModal: FC = memo(function FraudAlertModal() {\n const { closeModal } = useModalActions();\n const [countdown, setCountdown] = useState(10); // 10 seconds countdown\n\n const handleLogout = useCallback(() => {\n closeModal();\n }, [closeModal]);\n\n useEffect(() => {\n const timer = setInterval(() => {\n setCountdown(prev => {\n if (prev <= 1) {\n handleLogout();\n\n return 0;\n }\n\n return prev - 1;\n });\n }, 100000);\n\n return () => clearInterval(timer);\n }, [handleLogout]);\n\n return (\n <FlexView $gapX={1.5} $gutterX={1.5} $background=\"RED_1\">\n <FlexView\n $justifyContent=\"center\"\n $alignItems=\"center\"\n $borderRadiusX={4}\n $heightX={4.5}\n $widthX={4.5}\n $background=\"RED_2\"\n >\n <FlexView\n $justifyContent=\"center\"\n $alignItems=\"center\"\n $borderRadiusX={4}\n $heightX={3.5}\n $widthX={3.5}\n $background=\"RED_4\"\n >\n <Image src={ILLUSTRATIONS.ALERT_BULB} alt=\"Fraud Alert\" height={40} width={40} />\n </FlexView>\n </FlexView>\n <Separator heightX={2} />\n <Text $renderAs=\"ah4-bold\" $color=\"RED_6\">\n Fraudulent Login Detected!\n </Text>\n <Separator height={12} />\n <Text $renderAs=\"ub2\" color=\"BLACK_1\">\n You have logged into a student's LEAP account, which is strictly prohibited. This is\n considered{' '}\n <Text as=\"span\" $renderAs=\"ub2-bold\" color=\"BLACK_1\" $inline>\n fraudulent activity\n </Text>{' '}\n and may result in strict action, including a{' '}\n <Text as=\"span\" $renderAs=\"ub2-bold\" color=\"BLACK_1\" $inline>\n heavy penalty\n </Text>{' '}\n or{' '}\n <Text as=\"span\" $renderAs=\"ub2-bold\" color=\"BLACK_1\" $inline>\n discontinuation\n </Text>{' '}\n from conducting Cuemath classes.\n </Text>\n <Separator heightX={2} />\n <Button\n renderAs=\"primary\"\n alignSelf=\"flex-end\"\n shape=\"square\"\n onClick={handleLogout}\n label=\"Log out\"\n width=\"50%\"\n />\n </FlexView>\n );\n});\n\nexport default FraudAlertModal;\n"],"names":["FraudAlertModal","memo","closeModal","useModalActions","countdown","setCountdown","useState","handleLogout","useCallback","useEffect","timer","prev","FlexView","jsx","Image","ILLUSTRATIONS","Separator","Text","jsxs","Button","FraudAlertModal$1"],"mappings":";;;;;;;;;AAeA,MAAMA,IAAsBC,EAAK,WAA2B;AACpD,QAAA,EAAE,YAAAC,MAAeC,KACjB,CAACC,GAAWC,CAAY,IAAIC,EAAS,EAAE,GAEvCC,IAAeC,EAAY,MAAM;AAC1B,IAAAN;EAAA,GACV,CAACA,CAAU,CAAC;AAEf,SAAAO,EAAU,MAAM;AACR,UAAAC,IAAQ,YAAY,MAAM;AAC9B,MAAAL,EAAa,CAAQM,MACfA,KAAQ,KACGJ,KAEN,KAGFI,IAAO,CACf;AAAA,OACA,GAAM;AAEF,WAAA,MAAM,cAAcD,CAAK;AAAA,EAAA,GAC/B,CAACH,CAAY,CAAC,qBAGdK,GAAS,EAAA,OAAO,KAAK,UAAU,KAAK,aAAY,SAC/C,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAACD;AAAA,MAAA;AAAA,QACC,iBAAgB;AAAA,QAChB,aAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,SAAS;AAAA,QACT,aAAY;AAAA,QAEZ,UAAA,gBAAAC;AAAA,UAACD;AAAA,UAAA;AAAA,YACC,iBAAgB;AAAA,YAChB,aAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,UAAU;AAAA,YACV,SAAS;AAAA,YACT,aAAY;AAAA,YAEZ,UAAA,gBAAAC,EAACC,GAAM,EAAA,KAAKC,EAAc,YAAY,KAAI,eAAc,QAAQ,IAAI,OAAO,GAAI,CAAA;AAAA,UAAA;AAAA,QACjF;AAAA,MAAA;AAAA,IACF;AAAA,IACA,gBAAAF,EAACG,GAAU,EAAA,SAAS,EAAG,CAAA;AAAA,sBACtBC,GAAK,EAAA,WAAU,YAAW,QAAO,SAAQ,UAE1C,8BAAA;AAAA,IACA,gBAAAJ,EAACG,GAAU,EAAA,QAAQ,GAAI,CAAA;AAAA,IACtB,gBAAAE,EAAAD,GAAA,EAAK,WAAU,OAAM,OAAM,WAAU,UAAA;AAAA,MAAA;AAAA,MAEzB;AAAA,MACX,gBAAAJ,EAACI,GAAK,EAAA,IAAG,QAAO,WAAU,YAAW,OAAM,WAAU,SAAO,IAAC,UAE7D,sBAAA,CAAA;AAAA,MAAQ;AAAA,MAAI;AAAA,MACiC;AAAA,MAC7C,gBAAAJ,EAACI,GAAK,EAAA,IAAG,QAAO,WAAU,YAAW,OAAM,WAAU,SAAO,IAAC,UAE7D,gBAAA,CAAA;AAAA,MAAQ;AAAA,MAAI;AAAA,MACT;AAAA,MACH,gBAAAJ,EAACI,GAAK,EAAA,IAAG,QAAO,WAAU,YAAW,OAAM,WAAU,SAAO,IAAC,UAE7D,kBAAA,CAAA;AAAA,MAAQ;AAAA,MAAI;AAAA,IAAA,GAEd;AAAA,IACA,gBAAAJ,EAACG,GAAU,EAAA,SAAS,EAAG,CAAA;AAAA,IACvB,gBAAAH;AAAA,MAACM;AAAA,MAAA;AAAA,QACC,UAAS;AAAA,QACT,WAAU;AAAA,QACV,OAAM;AAAA,QACN,SAASZ;AAAA,QACT,OAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF,EAAA,CAAA;AAEJ,CAAC,GAEDa,IAAepB;"}
1
+ {"version":3,"file":"fraud-alert-modal.js","sources":["../../../../src/features/fraud-detection/fraud-alert-modal/fraud-alert-modal.tsx"],"sourcesContent":["/**\n * Fraud Alert Modal Component\n * Displays fraud detection details and auto-logout countdown\n */\n\nimport { memo, useCallback, useEffect, useState, type FC } from 'react';\n\nimport { useCaptureMediaStreamImage, useLocalPeer, useRemotePeers } from '@cuemath/av';\n\nimport { ILLUSTRATIONS } from '../../../assets/illustrations/illustrations';\nimport useModalActions from '../../ui/modals/use-modal-actions';\nimport Text from '../../ui/text/text';\nimport Image from '../../ui/image/image';\nimport FlexView from '../../ui/layout/flex-view';\nimport Button from '../../ui/buttons/button/button';\nimport Separator from '../../ui/separator/separator';\nimport useModalParams from '../../ui/modals/use-modal-params';\nimport useS3ImageUploadHelper from '../../worksheet/worksheet/hooks/use-s3-helper';\nimport { base64ToFile } from './fraud-alert-modal-helpers';\n\nconst QUERY = { type: 'fraud-login' };\n\nconst FraudAlertModal: FC = memo(function FraudAlertModal() {\n const { closeModal } = useModalActions();\n const { teacherId, studentId, handleLogout } = useModalParams<{\n teacherId: string;\n studentId: string;\n handleLogout: () => void;\n }>();\n const onLogout = useCallback(() => {\n closeModal();\n handleLogout();\n }, [closeModal, handleLogout]);\n\n const localpeer = useLocalPeer();\n const remotePeer = useRemotePeers().find(peer => peer.userId === teacherId);\n const captureMediaStreamImage = useCaptureMediaStreamImage();\n const uploadImages = useS3ImageUploadHelper({\n studentId,\n query: QUERY,\n });\n\n useEffect(() => {\n if (!remotePeer?.id || !localpeer?.id) {\n return;\n }\n\n const { image: teacherImage } = captureMediaStreamImage(remotePeer?.id, 'camera');\n const { image: studentImage } = captureMediaStreamImage(localpeer?.id, 'camera');\n const teacherFile = base64ToFile(teacherImage, `teacher-${Date.now()}.png`);\n const studentFile = base64ToFile(studentImage, `student-${Date.now()}.png`);\n\n if (!teacherFile || !studentFile) {\n console.error('Failed to convert images to files');\n\n return;\n }\n\n uploadImages({\n fileKey: `media/fraud-login/${studentId}/`,\n images: [\n { file: teacherFile, url: 'teacher' },\n { file: studentFile, url: 'student' },\n ],\n });\n }, [captureMediaStreamImage, localpeer?.id, remotePeer?.id, studentId, uploadImages]);\n\n return (\n <FlexView $gapX={1.5} $gutterX={1.5} $background=\"RED_1\">\n <FlexView\n $justifyContent=\"center\"\n $alignItems=\"center\"\n $borderRadiusX={4}\n $heightX={4.5}\n $widthX={4.5}\n $background=\"RED_2\"\n >\n <FlexView\n $justifyContent=\"center\"\n $alignItems=\"center\"\n $borderRadiusX={4}\n $heightX={3.5}\n $widthX={3.5}\n $background=\"RED_4\"\n >\n <Image src={ILLUSTRATIONS.ALERT_BULB} alt=\"Fraud Alert\" height={40} width={40} />\n </FlexView>\n </FlexView>\n <Separator heightX={2} />\n <Text $renderAs=\"ah4-bold\" $color=\"RED_6\">\n Fraudulent Login Detected!\n </Text>\n <Separator height={12} />\n <Text $renderAs=\"ub2\" color=\"BLACK_1\">\n You have logged into a student's LEAP account, which is strictly prohibited. This is\n considered{' '}\n <Text as=\"span\" $renderAs=\"ub2-bold\" color=\"BLACK_1\" $inline>\n fraudulent activity\n </Text>{' '}\n and may result in strict action, including a{' '}\n <Text as=\"span\" $renderAs=\"ub2-bold\" color=\"BLACK_1\" $inline>\n heavy penalty\n </Text>{' '}\n or{' '}\n <Text as=\"span\" $renderAs=\"ub2-bold\" color=\"BLACK_1\" $inline>\n discontinuation\n </Text>{' '}\n from conducting Cuemath classes.\n </Text>\n <Separator heightX={2} />\n <Button\n renderAs=\"primary\"\n alignSelf=\"flex-end\"\n shape=\"square\"\n onClick={onLogout}\n label=\"Log out\"\n width=\"50%\"\n />\n </FlexView>\n );\n});\n\nexport default FraudAlertModal;\n"],"names":["QUERY","FraudAlertModal","memo","closeModal","useModalActions","teacherId","studentId","handleLogout","useModalParams","onLogout","useCallback","localpeer","useLocalPeer","remotePeer","useRemotePeers","peer","captureMediaStreamImage","useCaptureMediaStreamImage","uploadImages","useS3ImageUploadHelper","useEffect","teacherImage","studentImage","teacherFile","base64ToFile","studentFile","FlexView","jsx","Image","ILLUSTRATIONS","Separator","Text","jsxs","Button","FraudAlertModal$1"],"mappings":"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"}
@@ -2,28 +2,28 @@ import { useState as g, useMemo as h, useCallback as k, useEffect as D } from "r
2
2
  import { generateDeviceFingerprint as C } from "../../fraud-detection/utils/device-fingerprint.js";
3
3
  import { extractHardwareProfile as u, getHardwareComparison as P, matchesCriticalHardware as v } from "../../fraud-detection/utils/hardware-profile-matcher.js";
4
4
  const x = (f) => {
5
- const { enabled: s = !1, deviceFingerprint: e, ipAddress: t } = f, [d, l] = g(!1), r = h(() => C(t || "unknown"), [t]), a = k(async () => {
5
+ const { enabled: s = !1, deviceFingerprint: e, ipAddress: t } = f, [d, l] = g(!1), r = h(() => C(t || "unknown"), [t]), o = k(async () => {
6
6
  if (r)
7
7
  try {
8
- let i = 0;
8
+ let n = 0;
9
9
  const p = 3;
10
- for (; !e && i < p; )
11
- await new Promise((F) => setTimeout(F, 500)), i++;
10
+ for (; !e && n < p; )
11
+ await new Promise((F) => setTimeout(F, 500)), n++;
12
12
  if (!e)
13
13
  return;
14
- const o = u(r, t || "unknown"), c = u(
14
+ const a = u(r, t || "unknown"), c = u(
15
15
  e,
16
16
  e.ip_address || "unknown"
17
- ), m = P(o, c), w = v(o, c);
18
- let n = !1;
19
- (w || r.fingerprint === e.fingerprint || t === e.ip_address && t !== "unknown" && m.similarity > 70) && (n = !0), n && l(!0);
20
- } catch (i) {
21
- console.error("[FraudDetection] Error during fraud check:", i);
17
+ ), m = P(a, c), w = v(a, c);
18
+ let i = !1;
19
+ (w || r.fingerprint === e.fingerprint || t === e.ip_address && t !== "unknown" && m > 70) && (i = !0), i && l(!0);
20
+ } catch (n) {
21
+ console.error("[FraudDetection] Error during fraud check:", n);
22
22
  }
23
23
  }, [e, r, t]);
24
24
  return D(() => {
25
- r && e && s && a();
26
- }, [r, e, a, s]), {
25
+ r && e && s && o();
26
+ }, [r, e, o, s]), {
27
27
  isFraud: d,
28
28
  deviceFingerprint: r
29
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-fraud-detection.js","sources":["../../../../src/features/hooks/use-fraud-detection/use-fraud-detection.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport type { IUseFraudDetection } from './use-fraud-detection-types';\nimport { generateDeviceFingerprint } from '../../fraud-detection/utils/device-fingerprint';\nimport {\n extractHardwareProfile,\n getHardwareComparison,\n matchesCriticalHardware,\n} from '../../fraud-detection/utils/hardware-profile-matcher';\n\nconst useFraudDetection: IUseFraudDetection = props => {\n const { enabled = false, deviceFingerprint, ipAddress } = props;\n const [isFraud, setIsFraud] = useState(false);\n const fp = useMemo(() => generateDeviceFingerprint(ipAddress || 'unknown'), [ipAddress]);\n\n const checkFraudDetection = useCallback(async () => {\n if (!fp) {\n return;\n }\n\n try {\n let attempts = 0;\n const maxAttempts = 3;\n\n while (!deviceFingerprint && attempts < maxAttempts) {\n await new Promise(resolve => setTimeout(resolve, 500));\n attempts++;\n }\n\n if (!deviceFingerprint) {\n return;\n }\n\n const studentProfile = extractHardwareProfile(fp, ipAddress || 'unknown');\n const teacherProfile = extractHardwareProfile(\n deviceFingerprint,\n deviceFingerprint.ip_address || 'unknown',\n );\n\n const comparison = getHardwareComparison(studentProfile, teacherProfile);\n const isCriticalMatch = matchesCriticalHardware(studentProfile, teacherProfile);\n\n let fraudDetected = false;\n\n if (isCriticalMatch) {\n fraudDetected = true;\n } else if (fp.fingerprint === deviceFingerprint.fingerprint) {\n fraudDetected = true;\n } else if (ipAddress === deviceFingerprint.ip_address && ipAddress !== 'unknown') {\n if (comparison.similarity > 70) {\n fraudDetected = true;\n }\n }\n\n if (fraudDetected) {\n setIsFraud(true);\n }\n } catch (error) {\n console.error('[FraudDetection] Error during fraud check:', error);\n }\n }, [deviceFingerprint, fp, ipAddress]);\n\n // Automatically run fraud detection when fingerprint and teacher fingerprint are both available\n useEffect(() => {\n if (fp && deviceFingerprint && enabled) {\n checkFraudDetection();\n }\n }, [fp, deviceFingerprint, checkFraudDetection, enabled]);\n\n return {\n isFraud,\n deviceFingerprint: fp,\n };\n};\n\nexport default useFraudDetection;\n"],"names":["useFraudDetection","props","enabled","deviceFingerprint","ipAddress","isFraud","setIsFraud","useState","fp","useMemo","generateDeviceFingerprint","checkFraudDetection","useCallback","attempts","maxAttempts","resolve","studentProfile","extractHardwareProfile","teacherProfile","comparison","getHardwareComparison","isCriticalMatch","matchesCriticalHardware","fraudDetected","error","useEffect","useFraudDetection$1"],"mappings":";;;AAUA,MAAMA,IAAwC,CAASC,MAAA;AACrD,QAAM,EAAE,SAAAC,IAAU,IAAO,mBAAAC,GAAmB,WAAAC,MAAcH,GACpD,CAACI,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtCC,IAAKC,EAAQ,MAAMC,EAA0BN,KAAa,SAAS,GAAG,CAACA,CAAS,CAAC,GAEjFO,IAAsBC,EAAY,YAAY;AAClD,QAAKJ;AAID,UAAA;AACF,YAAIK,IAAW;AACf,cAAMC,IAAc;AAEb,eAAA,CAACX,KAAqBU,IAAWC;AACtC,gBAAM,IAAI,QAAQ,CAAAC,MAAW,WAAWA,GAAS,GAAG,CAAC,GACrDF;AAGF,YAAI,CAACV;AACH;AAGF,cAAMa,IAAiBC,EAAuBT,GAAIJ,KAAa,SAAS,GAClEc,IAAiBD;AAAA,UACrBd;AAAA,UACAA,EAAkB,cAAc;AAAA,QAAA,GAG5BgB,IAAaC,EAAsBJ,GAAgBE,CAAc,GACjEG,IAAkBC,EAAwBN,GAAgBE,CAAc;AAE9E,YAAIK,IAAgB;AAEpB,SAAIF,KAEOb,EAAG,gBAAgBL,EAAkB,eAErCC,MAAcD,EAAkB,cAAcC,MAAc,aACjEe,EAAW,aAAa,QACVI,IAAA,KAIhBA,KACFjB,EAAW,EAAI;AAAA,eAEVkB,GAAO;AACN,gBAAA,MAAM,8CAA8CA,CAAK;AAAA,MACnE;AAAA,EACC,GAAA,CAACrB,GAAmBK,GAAIJ,CAAS,CAAC;AAGrC,SAAAqB,EAAU,MAAM;AACV,IAAAjB,KAAML,KAAqBD,KACTS;KAErB,CAACH,GAAIL,GAAmBQ,GAAqBT,CAAO,CAAC,GAEjD;AAAA,IACL,SAAAG;AAAA,IACA,mBAAmBG;AAAA,EAAA;AAEvB,GAEAkB,IAAe1B;"}
1
+ {"version":3,"file":"use-fraud-detection.js","sources":["../../../../src/features/hooks/use-fraud-detection/use-fraud-detection.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport type { IUseFraudDetection } from './use-fraud-detection-types';\nimport { generateDeviceFingerprint } from '../../fraud-detection/utils/device-fingerprint';\nimport {\n extractHardwareProfile,\n getHardwareComparison,\n matchesCriticalHardware,\n} from '../../fraud-detection/utils/hardware-profile-matcher';\n\nconst useFraudDetection: IUseFraudDetection = props => {\n const { enabled = false, deviceFingerprint, ipAddress } = props;\n const [isFraud, setIsFraud] = useState(false);\n const fp = useMemo(() => generateDeviceFingerprint(ipAddress || 'unknown'), [ipAddress]);\n\n const checkFraudDetection = useCallback(async () => {\n if (!fp) {\n return;\n }\n\n try {\n let attempts = 0;\n const maxAttempts = 3;\n\n while (!deviceFingerprint && attempts < maxAttempts) {\n await new Promise(resolve => setTimeout(resolve, 500));\n attempts++;\n }\n\n if (!deviceFingerprint) {\n return;\n }\n\n const studentProfile = extractHardwareProfile(fp, ipAddress || 'unknown');\n const teacherProfile = extractHardwareProfile(\n deviceFingerprint,\n deviceFingerprint.ip_address || 'unknown',\n );\n\n const comparison = getHardwareComparison(studentProfile, teacherProfile);\n const isCriticalMatch = matchesCriticalHardware(studentProfile, teacherProfile);\n\n let fraudDetected = false;\n\n if (isCriticalMatch) {\n fraudDetected = true;\n } else if (fp.fingerprint === deviceFingerprint.fingerprint) {\n fraudDetected = true;\n } else if (ipAddress === deviceFingerprint.ip_address && ipAddress !== 'unknown') {\n if (comparison > 70) {\n fraudDetected = true;\n }\n }\n\n if (fraudDetected) {\n setIsFraud(true);\n }\n } catch (error) {\n console.error('[FraudDetection] Error during fraud check:', error);\n }\n }, [deviceFingerprint, fp, ipAddress]);\n\n // Automatically run fraud detection when fingerprint and teacher fingerprint are both available\n useEffect(() => {\n if (fp && deviceFingerprint && enabled) {\n checkFraudDetection();\n }\n }, [fp, deviceFingerprint, checkFraudDetection, enabled]);\n\n return {\n isFraud,\n deviceFingerprint: fp,\n };\n};\n\nexport default useFraudDetection;\n"],"names":["useFraudDetection","props","enabled","deviceFingerprint","ipAddress","isFraud","setIsFraud","useState","fp","useMemo","generateDeviceFingerprint","checkFraudDetection","useCallback","attempts","maxAttempts","resolve","studentProfile","extractHardwareProfile","teacherProfile","comparison","getHardwareComparison","isCriticalMatch","matchesCriticalHardware","fraudDetected","error","useEffect","useFraudDetection$1"],"mappings":";;;AAUA,MAAMA,IAAwC,CAASC,MAAA;AACrD,QAAM,EAAE,SAAAC,IAAU,IAAO,mBAAAC,GAAmB,WAAAC,MAAcH,GACpD,CAACI,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtCC,IAAKC,EAAQ,MAAMC,EAA0BN,KAAa,SAAS,GAAG,CAACA,CAAS,CAAC,GAEjFO,IAAsBC,EAAY,YAAY;AAClD,QAAKJ;AAID,UAAA;AACF,YAAIK,IAAW;AACf,cAAMC,IAAc;AAEb,eAAA,CAACX,KAAqBU,IAAWC;AACtC,gBAAM,IAAI,QAAQ,CAAAC,MAAW,WAAWA,GAAS,GAAG,CAAC,GACrDF;AAGF,YAAI,CAACV;AACH;AAGF,cAAMa,IAAiBC,EAAuBT,GAAIJ,KAAa,SAAS,GAClEc,IAAiBD;AAAA,UACrBd;AAAA,UACAA,EAAkB,cAAc;AAAA,QAAA,GAG5BgB,IAAaC,EAAsBJ,GAAgBE,CAAc,GACjEG,IAAkBC,EAAwBN,GAAgBE,CAAc;AAE9E,YAAIK,IAAgB;AAEpB,SAAIF,KAEOb,EAAG,gBAAgBL,EAAkB,eAErCC,MAAcD,EAAkB,cAAcC,MAAc,aACjEe,IAAa,QACCI,IAAA,KAIhBA,KACFjB,EAAW,EAAI;AAAA,eAEVkB,GAAO;AACN,gBAAA,MAAM,8CAA8CA,CAAK;AAAA,MACnE;AAAA,EACC,GAAA,CAACrB,GAAmBK,GAAIJ,CAAS,CAAC;AAGrC,SAAAqB,EAAU,MAAM;AACV,IAAAjB,KAAML,KAAqBD,KACTS;KAErB,CAACH,GAAIL,GAAmBQ,GAAqBT,CAAO,CAAC,GAEjD;AAAA,IACL,SAAAG;AAAA,IACA,mBAAmBG;AAAA,EAAA;AAEvB,GAEAkB,IAAe1B;"}
package/dist/index.d.ts CHANGED
@@ -5016,8 +5016,8 @@ declare interface IUseFraudDetection {
5016
5016
  }
5017
5017
 
5018
5018
  declare interface IUseFraudDetectionParams {
5019
- enabled?: boolean;
5020
- deviceFingerprint: IDeviceFingerprint;
5019
+ enabled: boolean;
5020
+ deviceFingerprint?: IDeviceFingerprint;
5021
5021
  ipAddress?: string;
5022
5022
  }
5023
5023
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cuemath/leap",
3
- "version": "4.0.5-as1",
3
+ "version": "4.0.5-as3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -35,7 +35,7 @@
35
35
  "sideEffects": false,
36
36
  "devDependencies": {
37
37
  "@100mslive/hms-video-store": "0.10.8",
38
- "@cuemath/av": "3.0.9",
38
+ "@cuemath/av": "3.0.21-as4",
39
39
  "@cuemath/cue-message-broker": "1.0.37",
40
40
  "@cuemath/eslint-config": "2.4.0",
41
41
  "@cuemath/prettier-config": "1.0.4",