尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Local, unified successor to the two separate Sites projects. This folder is not deployed and is not tied to a Sites project ID. The original MLAM_DAW_SITE and MLAM_PLUGIN_SITE checkouts and hosted sites have not been deleted or modified by this consolidation.
/ and /plugins: green MLAM Studio Pro storefront, actual product artwork, rotating 360° Y-axis 3D logo, plugin prices/details/demo links, and DAW coming soon./tutorials: uploaded How to use videos, with seeking/range streaming./downloads: licensed ZIP downloads./checkout?product=...: same-site purchase destination. Payments are deliberately disabled until a real merchant provider is integrated./admin: MLAM Studio Pro Administration. Manage products, upload images, demo/full ZIPs and videos, view orders and issue/revoke download licenses./admin/login: owner-only Supabase email/password sign-in. The server allowlists one confirmed owner email through MLAM_ADMIN_EMAIL; admin/customer sessions use separate HttpOnly cookies./admin; the public storefront and customer-account screens do not show an Admin link. This is presentation only, not the authorization boundary: owner login and API guards remain mandatory. /admin?section=products, releases, or videos keeps the selected upload section through login. Unknown section values cannot become external redirects. Mobile Administration keeps visible text labels and sign-out instead of icon-only controls.Node.js 24+ required (built-in node:sqlite). Reproducible installation: pnpm install --frozen-lockfile using the included lockfile. The development machine uses local dependency junctions plus an isolated Supabase dependency runtime to avoid duplicating large packages on a nearly-full drive. Do not ship node_modules, node_modules-shared or .local-auth-runtime; install from package.json on the host.
npm run db:migrate
npm run dev
Open http://127.0.0.1:4180/; Admin is http://127.0.0.1:4180/admin on the same origin.
Responsive layouts cover storefront, account/checkout forms, tutorial videos, product dialogs and Administration. Fluid grids and wrapping controls fit narrow phones, tablets and desktop widths without hiding page overflow. The device-width viewport does not restrict browser zoom; touch controls have 44px targets and mobile form fonts are 16px.
Customer login/signup use a compact, light account card inspired by the owner's supplied reference: Log in/Create account navigation, email/password first, Google below, an accessible show/hide-password control, and MLAM green accents. Customer setup notices do not expose internal Supabase instructions. The signed-in customer page separates account details, verification status, purchases and useful download/tutorial links without inventing orders or license counts. Styling is scoped to customer pages; owner Administration and backend authentication are unchanged.
Admin uses the same Supabase project as customer authentication but remains owner-only: the confirmed Supabase account must match the server-only MLAM_ADMIN_EMAIL allowlist. There is no public Admin registration, customer metadata cannot grant Admin, and the role is checked server-side on every protected request. To set the local allowlist privately, double-click ADMIN-SETUP.cmd or run npm run admin:setup; this asks only for the confirmed Supabase email (never the password), writes MLAM_ADMIN_EMAIL to .env.local, and requires restarting the local server. On a hosted server, set that variable in the host's private environment instead. Customers and Admin keep separate Supabase cookies.
Supabase issues and refreshes the Admin session in an HttpOnly, SameSite=Lax cookie (Secure on HTTPS); each request verifies the user with Supabase and checks the allowlisted email. Admin login is limited to 5 attempts per normalized email per 15 minutes and 30 requests per source per 15 minutes. Explicit same-origin checks apply to every mutating API request. Do not expose port 4180 directly to the internet.
auth_throttle. Keys contain scoped SHA-256 digests instead of raw user identifiers or addresses. Blocked retries do not keep extending cooldowns. HTTP 429 includes Retry-After and Cache-Control: no-store.public/; SQL values are parameter-bound.MLAM_TRUST_PROXY_IP=1 ONLY when your sole reverse proxy strips and overwrites X-MLAM-Client-IP with its actual TCP peer address and direct access to Node is blocked. Never blindly trust X-Forwarded-For supplied by visitors.These measures reduce brute-force/enumeration risks, not guarantee immunity. A targeted attacker may still cause temporary account cooldowns. Production also requires proxy-level request limits, HTTPS, updates/backups and a security review; MFA for the owner is a recommended next layer.
MLAM_DATA_DIR defaults to ./data. This persistent folder contains mlam.sqlite and uploads/ outside public/. Licensed releases are not served as static assets. Public image/video routes are scoped to their own file prefixes. Migrations run at Node server startup; db:migrate also applies them explicitly. The first catalog visit seeds only demo product metadata, not actual ZIPs or orders.
Existing hosted data has NOT been migrated. Before cutting over, export and back up the old products, orders, licenses, tutorials, ZIPs and R2 objects using authenticated owner access. Import them into this database/storage preserving IDs, filenames and keys, then compare counts and test licensed downloads. Do not point to a new database and claim old purchases have transferred. Keep the old sites online until cutover is verified.
See DEPLOYMENT.md. The prepared route is one Render Node web service with a persistent disk for both the frontend/backend process and current SQLite/file storage. render.yaml configures a paid service and disk, but no account, domain, or billable resource has been created or purchased. Review the current price before applying the Blueprint. File storage can use Cloudflare R2 instead of the disk: set the four R2_* variables (see R2-SETUP.md) and run npm run storage:sync-r2 to copy existing uploads. The SQLite database still needs persistent storage.
Checkout now displays full name, email and preferred payment method. POST /api/checkout/prepare validates bounded input with database-backed quotas: 20 submissions per source and 5 per normalized email per 15 minutes. The same trusted-proxy requirements as login apply; without that configuration, source quotas are conservatively shared. Email entry is not signup, verified identity or account login. For valid input the server deliberately returns HTTP 503 PAYMENT_NOT_CONFIGURED: no contact data, order, charge or license is saved. Only scoped rate-limit digests are stored. HTTP 429 includes Retry-After; the form displays the cooldown and prevents duplicate clicks. Limits are enforced by the backend even if the browser form is bypassed.
/account/register and /account/login. Each server request uses a fresh @supabase/ssr client; sessions are in HttpOnly, SameSite=Lax cookies (Secure on HTTPS), with server-verified getUser() identity. Proxy refresh preserves cookie chunks and no-cache headers. Only a publishable/anon key is accepted. No service-role key, access token or password is returned to browser JavaScript. Google uses PKCE and minimal openid email profile scopes, not Gmail inbox access. /auth/callback exchanges a code using the original verifier cookie and restricts return paths to customer destinations on the configured origin. /auth/confirm supports confirmation-email token hashes for cross-device confirmation. Auth pages/callbacks are private/no-store.AUTH_NOT_CONFIGURED, not a pretend account. Enable email confirmation and configure SMTP for real customer delivery. Google also needs Google Cloud OAuth credentials in Supabase. Tests use only a local test provider, never real credentials.role metadata grants owner access; only the confirmed MLAM_ADMIN_EMAIL allowlist does. Admin and customer sessions use separate cookies. Legacy customer tables/data are preserved but legacy cookies are no longer accepted by website routes. Do not silently import old customer passwords into Supabase or link purchases solely by email.Reference: Next.js self-hosting, Node SQLite, OWASP password storage.
Append-only migration 0004_customer_accounts.sql added legacy customers and customer sessions; the Supabase switch preserves those tables without treating them as the current auth source. No existing owner/products/purchases tables are replaced. Language selection never changes product prices or currencies. Real payments and live provider configuration remain release gates.
Append-only migration 0005_product_description_languages.sql adds a description_translations JSON text column only. Original descriptions, uploads, product IDs, prices and statuses are unchanged. Description writes require owner authorization, use bounded input, reject unsupported language codes and limit each translation to 4000 characters. Public /api/products?language=fr returns the requested copy plus all available descriptions; the original owner data is retained for editing.