Merge branch 'feature/IO-2444-single-device-login' into release/2023-11-10

This commit is contained in:
Patrick Fic
2023-11-08 12:08:32 -08:00
4 changed files with 26889 additions and 2321 deletions

24522
client/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
"@apollo/client": "^3.7.9", "@apollo/client": "^3.7.9",
"@asseinfo/react-kanban": "^2.2.0", "@asseinfo/react-kanban": "^2.2.0",
"@craco/craco": "^7.0.0", "@craco/craco": "^7.0.0",
"@fingerprintjs/fingerprintjs": "^3.3.3", "@fingerprintjs/fingerprintjs": "^3.4.2",
"@jsreport/browser-client": "^3.1.0", "@jsreport/browser-client": "^3.1.0",
"@sentry/react": "^7.40.0", "@sentry/react": "^7.40.0",
"@sentry/tracing": "^7.40.0", "@sentry/tracing": "^7.40.0",

View File

@@ -1,15 +1,17 @@
import Fingerprint2 from "@fingerprintjs/fingerprintjs"; import FingerprintJS from "@fingerprintjs/fingerprintjs";
import * as Sentry from "@sentry/browser"; import * as Sentry from "@sentry/browser";
import { notification } from "antd"; import { notification } from "antd";
import axios from "axios";
import { setUserId, setUserProperties } from "firebase/analytics"; import { setUserId, setUserProperties } from "firebase/analytics";
import { import {
checkActionCode, checkActionCode,
confirmPasswordReset, confirmPasswordReset,
sendPasswordResetEmail,
signInWithEmailAndPassword, signInWithEmailAndPassword,
signOut, signOut,
sendPasswordResetEmail,
} from "firebase/auth"; } from "firebase/auth";
import { doc } from "firebase/firestore"; import { doc, getDoc, setDoc } from "firebase/firestore";
import { getToken } from "firebase/messaging";
import i18next from "i18next"; import i18next from "i18next";
import LogRocket from "logrocket"; import LogRocket from "logrocket";
import { all, call, delay, put, select, takeLatest } from "redux-saga/effects"; import { all, call, delay, put, select, takeLatest } from "redux-saga/effects";
@@ -20,6 +22,7 @@ import {
firestore, firestore,
getCurrentUser, getCurrentUser,
logImEXEvent, logImEXEvent,
messaging,
updateCurrentUser, updateCurrentUser,
} from "../../firebase/firebase.utils"; } from "../../firebase/firebase.utils";
import { import {
@@ -28,6 +31,7 @@ import {
sendPasswordResetSuccess, sendPasswordResetSuccess,
setAuthlevel, setAuthlevel,
setInstanceConflict, setInstanceConflict,
setInstanceId,
setLocalFingerprint, setLocalFingerprint,
signInFailure, signInFailure,
signInSuccess, signInSuccess,
@@ -39,9 +43,8 @@ import {
validatePasswordResetSuccess, validatePasswordResetSuccess,
} from "./user.actions"; } from "./user.actions";
import UserActionTypes from "./user.types"; import UserActionTypes from "./user.types";
import axios from "axios";
import { messaging } from "../../firebase/firebase.utils"; const fpPromise = FingerprintJS.load();
import { getToken } from "firebase/messaging";
export function* onEmailSignInStart() { export function* onEmailSignInStart() {
yield takeLatest(UserActionTypes.EMAIL_SIGN_IN_START, signInWithEmail); yield takeLatest(UserActionTypes.EMAIL_SIGN_IN_START, signInWithEmail);
@@ -148,17 +151,15 @@ export function* setInstanceIdSaga({ payload: uid }) {
try { try {
const userInstanceRef = doc(firestore, `userInstance/${uid}`); const userInstanceRef = doc(firestore, `userInstance/${uid}`);
const fingerprint = Fingerprint2.x64hash128( // Get the visitor identifier when you need it.
(yield Fingerprint2.getPromise({})).map((c) => c.value).join(""), const fp = yield fpPromise;
31 const result = yield fp.get();
); yield setDoc(userInstanceRef, {
yield userInstanceRef.set({
timestamp: new Date(), timestamp: new Date(),
fingerprint, fingerprint: result.visitorId,
}); });
yield put(setLocalFingerprint(fingerprint)); yield put(setLocalFingerprint(result.visitorId));
yield delay(5 * 60 * 1000); yield delay(5 * 60 * 1000);
if (process.env.NODE_ENV === "production") yield put(checkInstanceId(uid)); if (process.env.NODE_ENV === "production") yield put(checkInstanceId(uid));
} catch (error) { } catch (error) {
@@ -171,11 +172,9 @@ export function* onCheckInstanceId() {
} }
export function* checkInstanceIdSaga({ payload: uid }) { export function* checkInstanceIdSaga({ payload: uid }) {
try { try {
const userInstanceRef = doc(firestore, `userInstance/${uid}`); const snapshot = yield getDoc(doc(firestore, `userInstance/${uid}`));
const snapshot = yield userInstanceRef.get();
let fingerprint = yield select((state) => state.user.fingerprint); let fingerprint = yield select((state) => state.user.fingerprint);
yield put(setInstanceConflict());
if (snapshot.data().fingerprint === fingerprint) { if (snapshot.data().fingerprint === fingerprint) {
yield delay(5 * 60 * 1000); yield delay(5 * 60 * 1000);
yield put(checkInstanceId(uid)); yield put(checkInstanceId(uid));
@@ -215,7 +214,6 @@ export function* signInSuccessSaga({ payload }) {
console.log("Error updating Crisp settings.", error); console.log("Error updating Crisp settings.", error);
} }
// if (!payload.email.includes("@imex.")) yield put(setInstanceId(payload.uid));
setUserId(analytics, payload.email); setUserId(analytics, payload.email);
setUserProperties(analytics, payload); setUserProperties(analytics, payload);
yield logImEXEvent("redux_sign_in_success"); yield logImEXEvent("redux_sign_in_success");
@@ -289,6 +287,14 @@ export function* SetAuthLevelFromShopDetails({ payload }) {
: { validemail: false } : { validemail: false }
) )
); );
if (payload.features.singleDeviceOnly) {
const user = yield select((state) => state.user.currentUser);
if (!(user.email.includes("@imex.") || user.email.includes("@rome.")))
yield put(setInstanceId(user.uid));
}
try { try {
window.$crisp.push(["set", "user:company", [payload.shopname]]); window.$crisp.push(["set", "user:company", [payload.shopname]]);
if (authRecord[0] && authRecord[0].user.validemail) { if (authRecord[0] && authRecord[0].user.validemail) {

File diff suppressed because it is too large Load Diff