'use strict'; // ============================================================================ // 외부 서비스 연동 모듈 등록소 (v1.5.7, 요구 5·6) // // 웹메이커가 다른 제품으로 바꿔 쓸 수 있는 외부 서비스는 "종류(kind)" 로 묶고, 종류마다 연동 모듈을 하나씩 고른다. // source : 사이트 소스 보관(git 원격) — gitea (lib/connectors/gitea.js) // mail : 받는 메일·웹메일·메일 계정 서버 — arimail (lib/connectors/arimail.js, 구 mail-gateway) // 어느 모듈을 쓰는지는 설정 파일(lib/config.js)의 source.provider / mail.provider 가 정하고, 모듈이 접속에 쓰는 주소·계정도 // 같은 설정 파일(source.*, mail.*)에서 읽는다. 비밀값(토큰·비밀번호)은 암호화 보관소(lib/vault.js)에 있다. // // 모듈이 지켜야 하는 공통 모양 // id, label, kind 이름표 // settings() 설정 파일에서 읽은 접속 정보 (비밀값 포함, 서버 내부 전용) // configured() 동작에 필요한 값이 모두 있는지 // status() → Promise<{enabled, provider, ok, detail, …}> 연결 상태 (관리자 콘솔·설정 페이지 "연결 확인") // 종류별 추가 동작은 각 모듈 주석을 본다. 다른 제품(예: GitLab, 다른 메일 서버)으로 바꾸려면 같은 모양의 모듈을 이 폴더에 // 추가하고 아래 MODULES 와 config SCHEMA 의 provider 선택지에 넣으면 된다 — 나머지 코드(gitstore·mailsys)는 모듈만 본다. // ============================================================================ const MODULES = { source: { gitea: () => require('./gitea') }, mail: { arimail: () => require('./arimail') }, }; const KIND_LABEL = { source: '소스 보관', mail: '메일 서버' }; /** 설정에서 고른 모듈 id (source 는 기본 gitea, mail 은 기본 none) */ function providerOf(kind) { const config = require('../config'); const v = kind === 'source' ? config.get('source.provider') : config.get('mail.provider'); return v || (kind === 'source' ? 'gitea' : 'none'); } /** 지금 켜져 있는 모듈 (연동 안 함이면 null) */ function active(kind) { const f = (MODULES[kind] || {})[providerOf(kind)]; return f ? f() : null; } function source() { return active('source'); } function mail() { return active('mail'); } /** 모듈 목록 (화면용) */ function list() { return Object.entries(MODULES).flatMap(([kind, mods]) => Object.entries(mods).map(([id, f]) => { const m = f(); return { kind, kindLabel: KIND_LABEL[kind], id, label: m.label, active: providerOf(kind) === id, configured: m.configured() }; })); } /** 연결 상태. 모듈이 없으면(연동 안 함) 그 사실을 돌려준다 */ async function status(kind) { const m = active(kind); if (!m) return { enabled: false, provider: 'none', kind, ok: false, detail: `${KIND_LABEL[kind] || kind} 연동을 쓰지 않습니다 (설정 파일 ${kind}.provider = none)` }; try { return { kind, ...(await m.status()) }; } catch (e) { return { kind, enabled: true, provider: m.id, ok: false, detail: e.message }; } } /** "연결 확인" 버튼용 — {ok, detail} 로 간단히 */ async function test(kind) { const s = await status(kind); return { ok: !!s.ok, detail: s.detail, status: s }; } module.exports = { MODULES, KIND_LABEL, providerOf, active, source, mail, list, status, test };