BLA
BLA는 오픈소스 Blue Defense MCP와 CLI로, 소프트웨어 자산을 자동 AI 리버스 엔지니어링으로부터 보호합니다
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗기획서 Downloads/DATE_CHECK_MVP_개발자전달용_최종.docx 기준으로 만든 로컬 시험판이다.
npm start # PC 서버(dev.mjs) http://localhost:4040 관리자 /admin
npm test # 핵심 규칙 시험 (네트워크 없이)
npm run images # 배경 사진 3장 다시 만들기 (gpt-image-2, 비용 발생 — 오너 승인 뒤에만)
Node 20 이상, 외부 패키지 없음. 키는 .env.local.
| 키 | 쓰는 곳 |
|---|---|
GEMINI_API_KEY, GEMINI_MODEL | 대화 분석·캡처 글자 읽기·사진 관찰 (gemini-2.5-flash) |
NAVER_CLIENT_ID, NAVER_CLIENT_SECRET | 2026-10-22 부터 쓰지 않음 — 네이버 검색 API 약관(유료 서비스 사용·수익 행위 금지) 때문에 '네이버에서 직접 보기' 버튼으로 바꿈 |
GOOGLE_VISION_API_KEY (2026-10-26 연결 — GCP winaid-461106 키 datecheck-vision, Vision API 만 허용) | 사진 도용 확인 — 같은 사진이 올라간 웹페이지(구글 Cloud Vision 웹 검색). 넣으면 바로 켜진다 |
OPENAI_API_KEY | 배경 사진 생성 스크립트만 |
ADMIN_KEY | /admin 들어가는 키 |
DATA_GO_KR_KEY (2026-10-26 연결 — 공공데이터포털 계정 키 하나) | 국세청 사업자 상태 · 공정위 통신판매·방문판매·후원방문판매·다단계 · 금융위 기업기본정보 · 심평원 병원정보. API 마다 활용신청만 따로 |
SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY (2026-10-27 — Supabase 프로젝트 datecheck, 서울) | 로그인(Auth)과 데이터베이스(조회 기록·동의·횟수·문의). 서버에서만 쓰고 브라우저에는 보내지 않는다. 표 구조는 db/schema.sql |
REPORT_SECRET | 조회 기록 암호화 키(AES-256-GCM). ★운영에서 없으면 조회가 멈춘다 |
PRICE_VARIANTS·PRICE_CASEFILE·PRICE_RECHECK | 2026-10-27 결제를 없애며 뺐다 |
첫 화면(누구나) → 조회 시작 → 로그인·가입(이메일, 켜져 있으면 구글·카카오) → 약관 동의(처음 한 번) → 팝업에서 조회할 정보 선택(7종 — 2026-10-26 '이름'·'SNS 주소'·'쇼핑몰·사업체명'·'상대가 직접 말한 정보' 뺌) → 한 화면에 하나씩 입력 → 확인(이용자 책임·30일 보관 두 칸) → 13개 항목 결과가 바로 /report/아이디 → /my(내 조회)에서 30일 동안 다시 열기·지우기.
cleanInput 이 버린다.vercel.json regions: ["icn1"]. 전에는 미국 동부(iad1)에서 돌아 입력 전체가 국외로 나갔다. 구글 제미나이·Vision 으로 가는 대화·사진은 여전히 국외 이전 → 정식 처리방침에 적을 것(법 제28조의8)..ai-note)와 첫 화면 바닥글. 결과물 표시: AI 가 쓴 신호·사실(by: 'ai' — 대화 분석·사진 관찰)에 'AI 생성' 표시, 리포트 안내줄(.rp-ai), 신고용 정리본 '· AI 생성'. 같은 사진 웹 검색(Vision)은 생성형 AI 가 아니라 표시하지 않는다.api()(public/app.js) 하나로. 인터넷 끊김·연결 실패·늦음(504)·너무 큼(413)·JSON 아닌 답·서버 오류를 쉬운 말로 바꾸고, 점검·리포트 열기·문의는 화면에 남는 안내 + '다시 시도'. 설정을 못 받으면 점검 창 대신 안내와 '다시 시도'.next.why). 사진이 아닌 파일·HEIC·너무 큰 사진 안내. 대화 글 2만 자 넘으면 미리 알림.unsaved).busy()(lib/sources.mjs) 로 '무엇을 못 했는지 + 지금 할 수 있는 일(공식 화면 버튼)'. 이런 칸만 남은 항목은 상태 retry → '다시 확인 필요', 리포트 '잠시 확인하지 못한 항목' 구역. 키가 없어 못 하는 pending(연동 준비 중)과 구분. 공공데이터·국세청 조회는 연결 오류·5xx 한 번 더, 302 는 따라가지 않고 두 번까지 다시.clear(특이사항 없음)가 아니라 manual → '직접 확인 필요', 리포트 '직접 확인할 항목' 구역(2026-10-27 — 사기 계좌도 초록 칩으로 읽히던 것). 넣은 값을 되풀이한 문장은 tip.node scripts/hira-list.mjs — 진단 시스템(Desktop/winaid-diagnosis)의 data/hira/hospitals.json.gz 와 같은 원본 zip 의 약국 시트로 만든다(분기마다). vercel.json includeFiles: datasets/** 로 함수에 같이 실린다.
/api/pay 없음./api/analyze)·리포트(/api/report)·내 조회(/api/reports)·지우기. 첫 화면·안내 페이지·예시 리포트·약관·문의는 누구나.attest: true 가 없으면 받지 않는다. 약관 제4·5조(content/legal.mjs).dc_at 1시간, dc_rt 30일, SameSite=Lax·Secure) — 만료되면 서버가 갱신 토큰으로 바꿔 준다(lib/auth.mjs). 다른 사이트에서 온 POST(Origin 다름)는 거절. 구글·카카오는 PKCE(/api/auth/oauth → Supabase → /api/auth/callback), Supabase 에서 켜면 버튼이 자동으로 나온다(/api/config auth). 메일 링크(가입 확인·비밀번호 재설정)는 token_hash 로 /api/auth/confirm — 다른 기기에서 열어도 된다.CONSENT_VERSION(lib/auth.mjs) — 약관을 바꾸면 날짜를 올리면 모두 다시 동의한다.QUOTA, 데이터베이스 take_quota 가 계정·종류별로 잠그고 센다). 접속 주소 한도(LIMITS)는 1차 방어.mailer_autoconfirm 을 켜 둠(메일 확인 없이 가입). 비밀번호 찾기 메일을 쓰려면 SMTP(예: Gmail 앱 비밀번호, Resend)를 Supabase 에 붙이고 autoconfirm 을 끈다.C:/tmp/dc-auth(auth-config.mjs — 사이트 주소·돌아올 주소·한국어 메일, sql.mjs — db/schema.sql 적용).| 번호 | 항목 | 요금제 | 지금 |
|---|---|---|---|
| 1·2 | 전화번호·계좌번호 피해등록 | 무료 | 번호 종류는 자동. 공개 글은 네이버 직접 검색 버튼. 경찰민원24·더치트는 자동 조회하지 않고, 리포트의 '직접 조회' 버튼이 어디에 검색하는지 화면 캡처(빨간 상자)로 안내한다 |
| 3~7 | 금전요구·투자유도·개인정보 요구·회피·진술 불일치 | 정밀 | 됨 (제미나이만 — 2026-10-26 오너 '규칙 기반은 잘못 판별될 경우가 많다'로 규칙 엔진 삭제. 근거 문장은 원문 대조 후에만, '나:' 줄 근거는 버림) |
| 8 | 사진 도용 확인 | 정밀 | AI 관찰은 됨. 같은 사진 웹 검색 lib/vision.mjs 켜짐(10-26) |
| 9 | URL·도메인 검증 | 무료 | 됨 (등록일 RDAP, .kr 포함·닮은 주소·운영기간 비교). SNS·영상·블로그 주소(isSnsUrl)는 링크 칸·대화에서 걸러 확인하지 않는다 |
| 10 | 사업자 진위·상태 | 무료 | 번호 규칙은 됨. 국세청 상태조회 켜짐(10-26) — 계속·휴업·폐업·미등록 |
| 11 | 통신판매·방문판매 신고 | 무료 | 공정위 API(DATA_GO_KR_KEY 하나): 통신판매 등록상세·방문판매·후원방문판매, 모두 사업자등록번호로. 신고·상태·신고번호·신고 도메인. 사이트 주소까지 받았는데 신고가 없으면 '참고'. 다단계판매 등록은 12번 회사 이름으로 본다(2026-10-26 쇼핑몰·사업체명 입력 뺌). ★후원방문판매(15126329)·다단계(15126325·15126326)는 활용신청 승인 전이면 조용히 뺀다(이용자에게 '서버가 응답하지 않는다'고 하지 않음) |
| 12 | 회사 공개정보 | 무료 | 금융위 기업기본정보 — 같은 이름 법인만(법인등록번호마다 하나), 대표·설립일·본사. 사업자번호와는 대조하지 않는다(다니는 회사와 운영 사업체는 다른 곳). 다단계판매업자로 등록된 회사면 알림. 네이버 직접 검색·DART 전자공시 버튼. OpenDART 연동 안 함(10-26 오너) |
| 13 | 직업 공개정보 | 무료 | 심평원 병원정보 API(이름 일부, 진료과 낱말 떼며 3번) → 안 되면 분기 목록 datasets/hira-list.json.gz(병의원 79,772·약국 25,760, 2026-06). 약국은 처음부터 목록. 이름이 똑같은 곳이 여럿이면 한 곳을 내세우지 않고 지역 목록. ★심평원 API 는 우리 키만 옛 http 주소로 302 를 자주 돌려줌(10-26) |
성범죄자 알림e·경찰민원24·KISA 보호나라는 공식 조회 버튼만 둔다(STEP 8). 범죄경력은 다루지 않는다.
cleanInput 이 버린다.isSnsUrl(public/parse-input.js)로 걸러 확인하지 않는다. 화면은 링크 칸에 SNS 주소만 넣으면 이유를 알리고 다음을 막는다.public/kakao-export.js 가 브라우저 안에서 읽어, 고른 사람은 '나:' 나머지는 '상대:' 줄로 바꾼 글(chatText)만 서버로 보낸다. 이름과 파일은 서버로 가지 않는다.[이름] [오후 3:21] 메시지 와 날짜 구분선, 휴대폰 2026년 10월 26일 오후 3:21, 이름 : 메시지(아이폰은 점 날짜·24시간), 영어 판, 맥 CSV, 이 파일이 든 zip(사진까지 내보낸 경우, 나뉜 파일은 이름 순서로 이음). UTF-8·UTF-16·EUC-KR.tests/kakao-export.test.mjs(14개, zip 은 시험 안에서 만듦). 화면 시험 C:/tmp/datecheck-test/kakao/e2e.mjs(BASE, ai 를 붙이면 끝까지).copyField): 번호 + 복사 버튼, 누르면 2초간 '복사됨'. 클립보드가 막히면 번호를 선택해 둔다. 번호 글자에는 줄바꿈용 붙임 글자를 넣지 않는다(직접 끌어 복사해도 깨끗하게).public/img/howto/ — PC용 police-phone·police-account·thecheat.webp, 폰용(폭 600px 이하) *-m.webp, 크기는 sizes.json. 경찰민원24 폰용은 실제 모바일 화면 맨 위부터 조회 칸까지, 더치트 폰용은 PC 화면을 폰 폭에 맞게 자르고 선·꼬리표를 크게(더치트 모바일 화면은 자동 브라우저에서 열리지 않음).SHARP_PATH=… PLAYWRIGHT_PATH=… node scripts/howto-shots.mjs. 찍은 뒤 빨간 상자 위치를 눈으로 확인하고, 크기가 바뀌었으면 public/app.js 의 HOWTO size·sizeM 을 sizes.json 대로 맞출 것.lib/links.mjs 의 guide 표시, 화면 문구는 public/app.js 의 HOWTO./report/example = public/example-report.json(대화 43줄·번호 010-0000-0000 은 꾸민 자료, 사진은 사기에 자주 도용되는 유명인 사진의 예로 키아누 리브스 — 위키미디어 공용 CC BY-SA 4.0, Marybel Le Pape. 출처는 사진 창에 링크로, 안내 문구는 json note. 2026-10-26 오너가 연예인 사진으로 결정(초상권·퍼블리시티권 위험 안내 뒤)). 다시 만들 때는 C:/tmp/datecheck-test/full/capture.mjs → make-example.mjs.reports.sealed)에 30일 둔다. 데이터베이스에는 봉투와 목록용 숫자(검사한 항목·신호 수)만 — 데이터베이스가 새어도 내용은 안 보인다. 다른 계정으로는 안 열린다(행의 user_id 와 봉투 안 user 를 둘 다 본다). 30일이 지나면 pg_cron 이 매시간 지운다./my → 회원 탈퇴)하면 Supabase 회원을 지우고, 조회 기록·동의·횟수 기록이 함께 지워진다(on delete cascade).requests.data/(PC)·임시 폴더(Vercel)에는 개인정보 없는 화면 이벤트·API 호출 비용·관리자 접근 로그만 남는다.public/wrap.js, 글 요소에 class w).lib/ai.mjs BANNED).public/img/{hero,bench,cups}.jpg 는 gpt-image-2 로 만든 것(사람·손·글자 없음).glueText), 끝줄에 낱말 하나만 남는 자리는 런타임이 피한다.public/ 을 그대로 내보내고, /api/* 는 api/index.mjs 함수 하나가 받는다(vercel.json rewrites, 최대 60초). 처리 코드는 PC 서버와 같은 lib/app.mjs.server.mjs 로 두면 Vercel 이 서버로 잘못 잡으므로 dev.mjs 로 둔다.GEMINI_API_KEY, GEMINI_MODEL, ADMIN_KEY, REPORT_SECRET(긴 임의 문자열 — ★운영에서 없으면 점검이 멈춘다, 대체값 안 씀), DATA_GO_KR_KEY, GOOGLE_VISION_API_KEY. 네이버 키는 2026-10-22 네이버 검색 API 를 뺀 뒤 쓰지 않는다. 제미나이 키가 없으면 대화 항목은 '연동 준비 중'으로 나온다(규칙으로 대신 판별하지 않는다).vercel.json 이 모든 응답에 CSP(스크립트는 자기 사이트만, 글꼴은 jsdelivr, 사진은 data·blob)·X-Frame-Options DENY·nosniff·Referrer-Policy·Permissions-Policy. 횟수 제한 LIMITS(lib/app.mjs): 점검 같은 접속 주소 10분 12번·하루 60번, 문의 한 시간 5번, 관리자 키 틀림 15분 10번 — 함수 인스턴스마다 세는 1차 방어(영구 저장소를 붙이면 그쪽으로). 화면이 보내는 이벤트는 CLIENT_EVENTS 만 받는다(결제·매출 이벤트는 서버만). AI 지시문은 systemInstruction, 대화·캡처·사진은 자료로만(프롬프트 주입 막기).public/logo-mark.svg(말풍선 + 체크). 머리글·팝업·관리자·바닥글에 같은 모양.favicon.ico(16·32·48)·favicon.svg, 애플·안드로이드 아이콘, site.webmanifest, 검색엔진 로고 img/logo-512.png(Organization.logo), 공유 이미지 og.jpg(1200×630)./guide/*, 정적 HTML) — 쪽마다 머리말에 ItemList 하나·다른 가이드 6개(이름·주소·사진), 화면 카드는 본문 끝에 같은 순서·같은 사진. 카드 이름은 16자 이하·가운뎃점·괄호 없음(content/guides.mjs assertCardRules, tests/seo.test.mjs).https://…/(끝 /). 홈 첫 화면에는 카드 줄을 두지 않았다 — 홈 결과 카드까지 노리려면 첫 화면 400px 안에 카드 6장이 필요하다(플레이북).node scripts/build-guides.mjs (가이드 쪽·sitemap·robots·홈 머리말·홈 가이드 칸)SHARP_PATH=… PLAYWRIGHT_PATH=… node scripts/build-assets.mjsSHARP_PATH=… node scripts/gen-card-bg.mjs [slug] — 오너 승인 뒤에만SITE_URL=https://새주소 node scripts/build-guides.mjs 로 다시 만든다.