Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,5 @@ npm run dev # local dev — create a .dev.vars with AUTH_TOKEN=<anything>
## Hosted accounts (public beta)

An optional, separate hosted deployment supports email/password accounts with recovery codes (no email delivery), private file pools, revocable device tokens and strict account/global usage limits. [Try the hosted beta](https://shotsync-hosted.defiabell.workers.dev) (100 accounts). It runs on Workers Free, but measured login CPU exceeds the nominal free budget and may be throttled under load. Deployment prerequisites and limits are in [docs/hosted.md](docs/hosted.md). Existing self-hosted and read-only demo deployments keep their current behavior. Tooling now requires Node.js 22+.

Hosted authentication delegates passwords and browser sessions to Supabase Auth. Operators need a dedicated personal project; website registration uses server-side admission checks while public Supabase signup stays disabled. See the migration and failure-recovery notes in the hosted guide.
2 changes: 2 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,5 @@ npm run dev # 本地开发 —— 建一个含 AUTH_TOKEN=<任意串> 的
## 托管账号版(公开试用)

可独立部署邮箱+密码注册/登录、恢复码重置密码(无需发邮件)、多用户文件隔离、设备令牌和账号/全站限额。[打开托管服务](https://shotsync-hosted.defiabell.workers.dev)。当前免费版试用,限 100 个账号;登录 CPU 实测仍超过免费版标称预算,高负载下可能受限。部署与限制见 [docs/hosted.md](docs/hosted.md)。现有自部署和只读 demo 保持原有使用方式;开发工具链需要 Node.js 22+。

托管认证由 Supabase Auth 处理密码和浏览器会话,运营者需配置独立个人项目。网站注册先由服务端检查人数上限,Supabase 公开注册保持关闭;迁移、上线状态与故障处理见部署文档。
34 changes: 24 additions & 10 deletions docs/hosted.md

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions migrations/0004_managed_auth.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ALTER TABLE users ADD COLUMN auth_provider_id TEXT;
ALTER TABLE users ADD COLUMN auth_state TEXT NOT NULL DEFAULT 'legacy' CHECK(auth_state IN ('legacy','active','resetting'));
ALTER TABLE users ADD COLUMN auth_operation TEXT;
CREATE UNIQUE INDEX users_auth_provider ON users(auth_provider_id);
CREATE TABLE auth_registrations (
id TEXT PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
created_at INTEGER NOT NULL,
state TEXT NOT NULL DEFAULT 'pending' CHECK(state IN ('pending','failed','complete'))
);

CREATE TABLE revoked_auth_sessions (session_id TEXT PRIMARY KEY, expires_at INTEGER NOT NULL);
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@
},
"engines": {
"node": ">=22"
},
"dependencies": {
"jose": "^6.2.9"
}
}
4 changes: 3 additions & 1 deletion scripts/check-hosted-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ try {
const url=new URL(c.vars.PUBLIC_ORIGIN);
if(url.protocol!=='https:' || ['localhost','127.0.0.1'].includes(url.hostname) || url.origin!==c.vars.PUBLIC_ORIGIN)problems.push('PUBLIC_ORIGIN must be the canonical production HTTPS origin');
} catch {problems.push('PUBLIC_ORIGIN is required');}
if(!/^https:\/\/[a-z0-9]{20}\.supabase\.co$/.test(c.vars.SUPABASE_URL||''))problems.push('Set SUPABASE_URL to a dedicated personal Supabase project before deployment');
if(c.vars.SUPABASE_SECRET_KEY || c.vars.SUPABASE_PUBLISHABLE_KEY || c.vars.PASSWORD_PEPPER)problems.push('Secrets must not be stored in Wrangler vars');
if(!c.vars.TURNSTILE_SITE_KEY)problems.push('TURNSTILE_SITE_KEY is required');
if(!c.d1_databases?.[0]?.database_id || c.d1_databases[0].database_id==='00000000-0000-0000-0000-000000000000')problems.push('Set the dedicated hosted D1 database ID');
if(c.name!=='shotsync-hosted' || c.r2_buckets?.[0]?.bucket_name!=='shotsync-hosted')problems.push('Hosted Worker and bucket must remain separate from personal/demo instances');
if(problems.length){console.error(problems.join('\n'));process.exit(1);}
console.log('Hosted config ready. Confirm PASSWORD_PEPPER and Turnstile secrets, bucket lifecycle, and deployment authorization before publishing.');
console.log('Hosted config ready. Confirm SUPABASE_SECRET_KEY, SUPABASE_PUBLISHABLE_KEY and Turnstile secrets, disabled public provider signup, bucket lifecycle, and deployment authorization before publishing.');
Loading
Loading