@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.
- package/dist/features/fraud-detection/fraud-alert-modal/fraud-alert-modal-helpers.js +21 -0
- package/dist/features/fraud-detection/fraud-alert-modal/fraud-alert-modal-helpers.js.map +1 -0
- package/dist/features/fraud-detection/fraud-alert-modal/fraud-alert-modal.js +51 -34
- package/dist/features/fraud-detection/fraud-alert-modal/fraud-alert-modal.js.map +1 -1
- package/dist/features/hooks/use-fraud-detection/use-fraud-detection.js +12 -12
- package/dist/features/hooks/use-fraud-detection/use-fraud-detection.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/package.json +2 -2
|
@@ -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
|
|
2
|
-
import { memo as
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
44
|
-
/* @__PURE__ */ e(
|
|
45
|
-
/* @__PURE__ */ e(
|
|
46
|
-
/* @__PURE__ */
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
78
|
+
/* @__PURE__ */ e(s, { heightX: 2 }),
|
|
62
79
|
/* @__PURE__ */ e(
|
|
63
|
-
|
|
80
|
+
w,
|
|
64
81
|
{
|
|
65
82
|
renderAs: "primary",
|
|
66
83
|
alignSelf: "flex-end",
|
|
67
84
|
shape: "square",
|
|
68
|
-
onClick:
|
|
85
|
+
onClick: p,
|
|
69
86
|
label: "Log out",
|
|
70
87
|
width: "50%"
|
|
71
88
|
}
|
|
72
89
|
)
|
|
73
90
|
] });
|
|
74
|
-
}),
|
|
91
|
+
}), V = D;
|
|
75
92
|
export {
|
|
76
|
-
|
|
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
|
|
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]),
|
|
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
|
|
8
|
+
let n = 0;
|
|
9
9
|
const p = 3;
|
|
10
|
-
for (; !e &&
|
|
11
|
-
await new Promise((F) => setTimeout(F, 500)),
|
|
10
|
+
for (; !e && n < p; )
|
|
11
|
+
await new Promise((F) => setTimeout(F, 500)), n++;
|
|
12
12
|
if (!e)
|
|
13
13
|
return;
|
|
14
|
-
const
|
|
14
|
+
const a = u(r, t || "unknown"), c = u(
|
|
15
15
|
e,
|
|
16
16
|
e.ip_address || "unknown"
|
|
17
|
-
), m = P(
|
|
18
|
-
let
|
|
19
|
-
(w || r.fingerprint === e.fingerprint || t === e.ip_address && t !== "unknown" && m
|
|
20
|
-
} catch (
|
|
21
|
-
console.error("[FraudDetection] Error during fraud check:",
|
|
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 &&
|
|
26
|
-
}, [r, e,
|
|
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
|
|
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
|
|
5020
|
-
deviceFingerprint
|
|
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-
|
|
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.
|
|
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",
|