91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
import { decodeWithPassword, encodeWithPassword } from "@/app/crypto/crypto";
|
||
import { useFileStorage } from "@/app/hooks/useFileStorage";
|
||
import { generateRandomKey } from "@/app/utils/utils";
|
||
import { createContext, useEffect, useState } from "react";
|
||
|
||
interface SystemProviderContextValue {
|
||
id: string;
|
||
name: string;
|
||
os: string;
|
||
}
|
||
|
||
export const SystemProviderContext = createContext<SystemProviderContextValue|null>(null);
|
||
|
||
export interface SystemProviderProps {
|
||
children?: React.ReactNode;
|
||
}
|
||
|
||
/**
|
||
* Предоставляет информацию о системе и обезличенный
|
||
* идентификатор устройства.
|
||
*/
|
||
export function SystemProvider(props: SystemProviderProps) {
|
||
const [deviceId, setDeviceId] = useState<string>("");
|
||
const {writeFile, readFile} = useFileStorage();
|
||
|
||
useEffect(() => {
|
||
fetchDeviceId();
|
||
}, []);
|
||
|
||
const fetchDeviceId = async () => {
|
||
const device = await readFile("device");
|
||
if(device){
|
||
const decoded = await decodeDevice(Buffer.from(device).toString('utf-8'));
|
||
if(decoded){
|
||
setDeviceId(decoded);
|
||
return;
|
||
}
|
||
}
|
||
await createDeviceId();
|
||
}
|
||
|
||
const createDeviceId = async () => {
|
||
const newDevice = generateRandomKey(128);
|
||
const encoded = await encodeDevice(newDevice);
|
||
await writeFile("device", encoded);
|
||
setDeviceId(newDevice);
|
||
}
|
||
|
||
const decodeDevice = async (data: string) => {
|
||
const hwid = window.deviceId;
|
||
const platform = window.deviceName;
|
||
const salt = "rosetta-device-salt";
|
||
|
||
try {
|
||
const decoded = await decodeWithPassword(hwid + platform + salt, data);
|
||
return decoded;
|
||
} catch (e) {
|
||
console.error("Failed to decode device data:", e);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
const encodeDevice = async (data: string) => {
|
||
const hwid = window.deviceId;
|
||
const platform = window.deviceName;
|
||
const salt = "rosetta-device-salt";
|
||
|
||
try {
|
||
const encoded = await encodeWithPassword(hwid + platform + salt, data);
|
||
return encoded;
|
||
} catch (e) {
|
||
console.error("Failed to encode device data:", e);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
const systemName = window.deviceName || "Unknown Device";
|
||
const systemOs = window.platform || "Unknown OS";
|
||
|
||
|
||
|
||
return (
|
||
<SystemProviderContext.Provider value={{
|
||
id: deviceId,
|
||
name: systemName,
|
||
os: systemOs
|
||
}}>
|
||
{props.children}
|
||
</SystemProviderContext.Provider>
|
||
);
|
||
} |