fix(A00·B07 CAD): http + IP 주소(Tailscale)에서 CAD 가 죽던 것 — crypto.randomUUID 대체
보안 문맥이 아닌 http + IP 에서는 crypto.randomUUID 가 없어 CAD 개체 만들기에서 멈춤. 앱 본체(A00_Common/main.ts)와 CAD(openwebcad/src/main.tsx) 진입 맨 앞에서 getRandomValues 로 v4 UUID 를 채움 · 이미 있으면 그대로. crypto.subtle(B03 지문) · serviceWorker(B03) 는 이미 없을 때 건너뜀 · navigator.clipboard 는 안 씀. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K7JS47SacjPxZ718QsZKyr
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
* - hashchange 1회 구독: 셸 chrome 갱신 + 현재 라우트 렌더
|
||||
* ========================================================================== */
|
||||
|
||||
import "./random_uuid_polyfill";
|
||||
import "@ui/ui_template_theme.css";
|
||||
import { injectBaseStyles } from "@ui/ui_template_elements";
|
||||
import { ROUTES, type RoutePath } from "@config/config_frontend";
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* http + IP 주소(예: Tailscale)는 보안 문맥이 아니라 `crypto.randomUUID` 가 없음.
|
||||
* getRandomValues(보안 문맥 아니어도 됨)로 v4 UUID 를 채움 · 이미 있으면 그대로.
|
||||
* `main.ts` 가 맨 먼저 부름. CAD 짝 = `B07_DesignDetail/openwebcad/src/random-uuid-polyfill.ts`.
|
||||
*/
|
||||
if (typeof crypto !== "undefined" && typeof crypto.randomUUID !== "function") {
|
||||
crypto.randomUUID = () => {
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
||||
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}` as `${string}-${string}-${string}-${string}-${string}`;
|
||||
};
|
||||
}
|
||||
|
||||
export {};
|
||||
@@ -1,3 +1,4 @@
|
||||
import './random-uuid-polyfill';
|
||||
import { Point } from '@flatten-js/core';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* http + IP 주소(예: Tailscale)는 보안 문맥이 아니라 `crypto.randomUUID` 가 없음 — 개체 만들기에서 죽음.
|
||||
* getRandomValues(보안 문맥 아니어도 됨)로 v4 UUID 를 채움 · 이미 있으면 그대로.
|
||||
* `main.tsx` 가 맨 먼저 부름. 앱 본체 짝 = `A00_Common/random_uuid_polyfill.ts`.
|
||||
*/
|
||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID !== 'function') {
|
||||
crypto.randomUUID = () => {
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');
|
||||
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}` as `${string}-${string}-${string}-${string}-${string}`;
|
||||
};
|
||||
}
|
||||
|
||||
export {};
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* http + IP(보안 문맥 아님)에서 비는 crypto.randomUUID 대체 검증 — CAD · 앱 본체 두 벌.
|
||||
* 실행: node --experimental-strip-types resources/tester/cad/random-uuid-polyfill.test.ts
|
||||
*/
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
const V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
||||
const native = crypto.randomUUID;
|
||||
|
||||
for (const path of [
|
||||
'../../../B07_DesignDetail/openwebcad/src/random-uuid-polyfill.ts',
|
||||
'../../../A00_Common/random_uuid_polyfill.ts',
|
||||
]) {
|
||||
// biome-ignore lint: 시험 — 보안 문맥 아닌 브라우저처럼 비움
|
||||
(crypto as any).randomUUID = undefined;
|
||||
await import(`${path}?${Math.random()}`);
|
||||
const ids = Array.from({ length: 200 }, () => crypto.randomUUID());
|
||||
assert.ok(ids.every((id) => V4.test(id)), `${path}: v4 모양`);
|
||||
assert.equal(new Set(ids).size, ids.length, `${path}: 안 겹침`);
|
||||
}
|
||||
|
||||
// 이미 있으면 그대로
|
||||
crypto.randomUUID = native;
|
||||
await import(`../../../A00_Common/random_uuid_polyfill.ts?${Math.random()}`);
|
||||
assert.equal(crypto.randomUUID, native, '원래 것 유지');
|
||||
console.log('random-uuid 대체 시험 통과');
|
||||
Reference in New Issue
Block a user