feat(t54): 小幫手憑帳密自取設定——新端點 POST /portal/daemon/config(帳密驗證同 login,回連線設定不含知識內容);portal 清單移除 config.json 下載(3 步→2 步)。leo 07-25:「最好的就是把它的帳密直接輸入」
This commit is contained in:
@@ -676,7 +676,7 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
var p = S.profile || {};
|
||||
if (p.role !== 'admin') return;
|
||||
var s = setupSteps();
|
||||
if (s.daemon && s.config && s.key) return; // 三件齊=安裝真的完成,不再打擾
|
||||
if (s.daemon && s.key) return; // t54 起只剩兩件:設定改由小幫手輸入帳密自取,不再下載檔案
|
||||
var cfg = window.ARCRUN_CONFIG || {};
|
||||
var daemonUrl = cfg.daemonDownload || 'https://raw.githubusercontent.com/youlinhsieh/arcrun-rag-bundles/main/daemon/ArcrunRAG-mac-unsigned.zip';
|
||||
var row = function (done, id, html) {
|
||||
@@ -686,7 +686,7 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
var el = document.createElement('div');
|
||||
el.id = 'setup-checklist';
|
||||
el.style.cssText = 'position:fixed;right:20px;bottom:20px;z-index:60;max-width:400px;width:calc(100% - 40px);padding:18px 20px;border-radius:14px;background:rgba(var(--amber-rgb),.10);border:1px solid rgba(var(--amber-rgb),.45);backdrop-filter:blur(8px);font-size:14px;line-height:1.65';
|
||||
el.innerHTML = '<b>還差 ' + (3 - (s.daemon?1:0) - (s.config?1:0) - (s.key?1:0)) + ' 步,安裝就真的完成了</b>'
|
||||
el.innerHTML = '<b>還差 ' + (2 - (s.daemon?1:0) - (s.key?1:0)) + ' 步,安裝就真的完成了</b>'
|
||||
+ row(s.daemon, 'daemon',
|
||||
'<b>下載同步小幫手</b>(把資料夾變成知識庫)<br>'
|
||||
+ (daemonUrl
|
||||
@@ -695,10 +695,10 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
// 誠實降級(leo 判準:按了連到錯的機制=不友善):沒有可用下載點時
|
||||
// 不放死連結,說明現況並讓這步可手動打勾,不卡住清單。
|
||||
: '<span class="muted" style="font-size:13px">封測期由我們直接寄給你安裝檔(Mac 版);'
|
||||
+ '收到後回來按 <a href="#" id="sc-daemon">我已經裝好了</a>。</span>'))
|
||||
+ row(s.config, 'config',
|
||||
'<b>下載設定檔</b> 放到 <code style="font-size:12px">~/.arcrun-rag/config.json</code><br>'
|
||||
+ '<a href="#" id="sc-config">下載 config.json</a>')
|
||||
+ '收到後回來按 <a href="#" id="sc-daemon">我已經裝好了</a>。</span>')
|
||||
// t54(leo:「最好的就是把它的帳密直接輸入」):設定不再是一個要下載的檔案——
|
||||
// 小幫手第一次開啟會問網址+帳密,自己去換設定。
|
||||
+ '<div class="muted" style="font-size:12.5px;margin-top:4px">裝好第一次開啟時,貼上這個網址+你的帳號密碼就連上了,不用下載設定檔。</div>')
|
||||
+ row(s.key, 'key',
|
||||
'<b>啟用 AI 問答</b>(<a href="https://aistudio.google.com" target="_blank" rel="noopener">aistudio.google.com</a> 免費申請)<br>'
|
||||
+ '<input id="sc-key" type="password" placeholder="貼上 Google AI 金鑰" style="width:60%;padding:6px 8px;border-radius:8px;border:1px solid rgba(var(--ink-rgb),.25);background:rgba(var(--ink-rgb),.04);color:var(--ink)"> '
|
||||
@@ -708,24 +708,7 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
document.body.appendChild(el);
|
||||
var dl = document.getElementById('sc-daemon');
|
||||
if (dl) dl.addEventListener('click', function () { markStep('daemon'); });
|
||||
var cb = document.getElementById('sc-config');
|
||||
if (cb) cb.addEventListener('click', function (ev) {
|
||||
ev.preventDefault();
|
||||
var conf = {
|
||||
watch_folders: [],
|
||||
manifest: '~/.arcrun-rag/manifest.json',
|
||||
cypher_url: cfg.apiBase || '',
|
||||
namespace: cfg.tenant || '',
|
||||
library: 'kb',
|
||||
extractor: 'claude',
|
||||
email: (S.profile && S.profile.email) || ''
|
||||
};
|
||||
var a = document.createElement('a');
|
||||
a.href = 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(conf, null, 2));
|
||||
a.download = 'config.json';
|
||||
document.body.appendChild(a); a.click(); a.remove();
|
||||
markStep('config');
|
||||
});
|
||||
// t54:config.json 下載鈕已移除(設定由小幫手憑帳密自取)
|
||||
var kb = document.getElementById('sc-key-save');
|
||||
if (kb) kb.addEventListener('click', function () {
|
||||
var k = (document.getElementById('sc-key').value || '').trim();
|
||||
|
||||
@@ -699,6 +699,46 @@ function toPublicLibrary(rec: PortalRecord) {
|
||||
};
|
||||
}
|
||||
|
||||
// POST /portal/daemon/config — body {email, password}。同步小幫手憑「用戶剛設的帳密」
|
||||
// 直接換到自己的設定(t54,leo 07-25:「最好的就是把它的帳密直接輸入」)——
|
||||
// 用戶不必再下載 config.json 丟隱藏資料夾,托盤第一次開啟輸入網址+帳密就上工。
|
||||
// 認證=與 /portal/login 同一把(同樣吃節流與停用檢查);回傳只含連線設定,不含任何知識內容。
|
||||
portalRouter.post('/portal/daemon/config', (c) =>
|
||||
run(c, async () => {
|
||||
const body = (await c.req.json().catch(() => null)) as { email?: string; password?: string } | null;
|
||||
const email = String(body?.email ?? '').trim().toLowerCase();
|
||||
const password = String(body?.password ?? '');
|
||||
if (!email || !password) return c.json({ error: 'email 與 password 必填' }, 400);
|
||||
if (await isLocked(c.env, email)) {
|
||||
return c.json({ error: '登入失敗次數過多,已暫時鎖定,請 15 分鐘後再試' }, 429);
|
||||
}
|
||||
const recordId = await findUserRecordId(c.env, email);
|
||||
const rec = recordId ? await getRecordById(c.env, recordId) : null;
|
||||
if (!rec) {
|
||||
await recordLoginFail(c.env, email);
|
||||
return c.json({ error: 'email 或密碼錯誤' }, 401);
|
||||
}
|
||||
if ((rec.values.status ?? '') !== 'active') return c.json({ error: '帳號已停用' }, 403);
|
||||
if (!(await verifyPassword(password, rec.values.password_hash ?? ''))) {
|
||||
await recordLoginFail(c.env, email);
|
||||
return c.json({ error: 'email 或密碼錯誤' }, 401);
|
||||
}
|
||||
await clearLoginFail(c.env, email);
|
||||
const tenant = portalTenant(c.env);
|
||||
return c.json({
|
||||
success: true,
|
||||
config: {
|
||||
cypher_url: new URL(c.req.url).origin,
|
||||
namespace: tenant,
|
||||
library: 'kb',
|
||||
extractor: 'claude',
|
||||
email,
|
||||
instance_name: String(rec.values.display_name ?? ''),
|
||||
},
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// POST /portal/admin/chat-key — body {key}。站內啟用 AI 問答(t53,leo 07-25:
|
||||
// 「他進到網站要去給 gemini API Key」——不再回安裝器)。手法=G10 直嵌同款:
|
||||
// 改寫 tenant 的 rag_chat workflow 記錄,把 x-goog-api-key 換成實值(KV 覆寫=重推)。
|
||||
|
||||
Reference in New Issue
Block a user