Open Net Worth
Open Net Worth는 직접 운영하는 오픈소스 개인 AI 자산 비서로, 전체 재무를 하나의 원장에 기록하고 사용자가 제어하는 AI가 관리
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A mobile-friendly personal finance diary. Users log what they spend and what they earn each day. The app shows the daily total, analyses each week, month and year, and exports full PDF statements. It works in English and বাংলা, with three themes: light cream (default), dark and a hand-drawn sketchbook theme.
| Area | What it does |
|---|---|
| Accounts | Sign up / log in with a username and password, or Continue with Google (any Gmail account). A one-time recovery code resets a forgotten password without losing data. |
| Daily log | Choose expense or income, write what it was for, then enter the amount and category. The day's total spending is always shown. |
| Past days locked | Adding, editing or deleting entries on a day that has passed needs the password again. Editing then stays unlocked for 5 minutes. |
| Analysis | Week (Saturday to Friday), month and year views with charts, category breakdown, comparison with the previous period, savings rate and insights. |
| Monthly target | Set a spending limit for the month on days 1–3 only (then it locks). Crossing it shows an alert, a system notification and sends an email, once per month. |
| Currency | Bangladeshi Taka (৳) by default. Pick another currency in Settings → Currency: new entries are saved in it and every total, target and report is shown in it. Older entries keep their original amount and are converted at the live rate. The change and its date are written into PDF reports. |
| In Taka | A tab with the live rate of your currency to Taka, a converter, and your day / month / year totals in Taka. Rates come from ExchangeRate-API (free, no key; Google Finance has no public API), with jsDelivr's currency-api as a backup, cached 6 hours in the database. |
| Loans | Log money you borrowed or lent (person, amount, date, optional return date). A loan stays open — on the Daily page and in Loans & Savings — until it is paid back; repayments can be partial, and it closes itself when the full amount is repaid. Overdue loans are flagged. |
| Savings | Put money into or take money out of savings; every change is logged. Shows your balance, how much you saved each of the last 6 months, and whether you are saving this month. You can't take out more than you have. |
| Every account confirms its own email with a 6-digit code (or via Google). Log in with username or email. | |
| Month-end report | When a month ends, its full PDF is emailed automatically (can be switched off). Monthly and yearly PDFs can still be downloaded any time. |
| Monthly and yearly statements with summary, category bars, day-by-day or month-by-month totals and every transaction, in English or Bangla. | |
| Onboarding | A "what is what" slide tour after the first sign-up (swipe on phones). It can be replayed from Settings. |
| Privacy | Users see only their own data. Admins see only counts and anonymous activity signals and can send warnings that the user must acknowledge. |
| Mobile | Responsive layout, bottom navigation on phones, safe-area support and an installable web-app manifest. |
android/ holds the Play Store app. It is a Trusted Web Activity that opens this
same site, so it uses the same database and accounts. GitHub Actions builds the APK and AAB.
See docs/ANDROID.md for building, signing and publishing step by step.npm test includes test/security.test.js, 99 black-box checks against a production-mode server.The parts you already know: HTML, CSS and vanilla JavaScript in the browser, and Node.js on the server. A few small, well-known additions:
| Added | Why |
|---|---|
| Express 5 | The standard, minimal Node web framework for routes and middleware. |
PostgreSQL (pg, hosted on Neon) | The database. Locally, without DATABASE_URL, the same SQL runs on PGlite (Postgres inside Node), so there is nothing to install. |
Node's built-in crypto | scrypt password hashing and AES-256-GCM encryption, with no extra crypto dependencies. |
| Chart.js | Charts on the reports page, served locally rather than from a CDN. |
| google-auth-library | Verifies "Continue with Google" sign-ins on the server (Google's official library). |
| PDFKit | Generates PDFs on the server. The bundled Noto Sans Bengali font renders Bangla correctly. |
| helmet and express-rate-limit | Security headers (a strict CSP) and brute-force protection. |
No frontend framework or build step is involved: edit a file and refresh the page.
SMTP_HOST=smtp.gmail.com, SMTP_PORT=465, SMTP_USER=<that Gmail>, SMTP_PASS=<the app password> and MAIL_FROM=Finance Baba <that Gmail>.Gmail allows about 500 emails a day, plenty for a personal project. Any other SMTP service (Brevo, Zoho, …) works the same way. Until email is set up, sign-up still works and the email step is skipped.
Month-end reports are sent by a daily job: on Vercel by Vercel Cron at 19:15 UTC, which is 1:15 AM in Bangladesh (vercel.json, needs CRON_SECRET), on your own server by a timer inside npm start. Each user's previous month is sent once, according to their own time zone.
Even a full copy of the database is useless to an attacker:
sessions table encrypted with a key derived from the random token in their cookie. The database only stores a hash of that token, so it cannot unlock the key on its own. Sessions end after 30 minutes idle or 12 hours.HttpOnly and SameSite=Strict, with a CSRF header check, a strict Content-Security-Policy and account lockout after 5 wrong passwords.⚠️ Keep
APP_SECRETsafe (ordata/secret.keywhen running locally without it). Without it, nothing in the database can be decrypted. Users who lose both their password and their recovery code cannot get their data back. That is by design.
npm install
cp .env.example .env # optional; a secret is auto-generated if APP_SECRET is empty
npm start # http://localhost:3000
npm run dev # same, but restarts on file changes
Create an admin account, either by setting ADMIN_USERNAME and ADMIN_PASSWORD in .env (created on the next start), or with the command below while the server is stopped (it asks for the password):
npm run create-admin -- admin "Site Admin"
Admins log in on the normal login page and are sent to /admin.
http://localhost:3000 and https://financebaba.vercel.app..env (and in Vercel's environment variables) as GOOGLE_CLIENT_ID=...apps.googleusercontent.com and restart / redeploy.The Google button appears only when GOOGLE_CLIENT_ID is set. First-time Google users still choose a username and password: the password protects past days and works as a fallback login. Existing users can connect or disconnect Google under Settings.
Run the tests:
npm test
To test on your phone, run the server and open http://<your-computer-ip>:3000 on the same Wi-Fi.
server/
config.js Settings and server secret
crypto.js Key derivation, AES-GCM, recovery codes
app.js Express app (shared by local server and Vercel)
index.js Local entry point (`npm start`)
db.js Postgres schema and queries (Neon via pg, or local PGlite)
bootstrap.js Creates the admin from ADMIN_USERNAME/ADMIN_PASSWORD
rateLimitStore.js Rate limits stored in Postgres
users.js Sign-up, login, lockout, password change, recovery, Google linking
google.js Google ID-token verification
sessions.js Database sessions (data key encrypted with the cookie token)
entries.js Encrypted entry storage and validation
dates.js Date helpers in the user's time zone
routes/ auth, entries (+ warnings), reports, admin
reports/ summary (analysis) and pdf (PDFKit statement)
shared/categories.js Categories with English and Bangla labels (browser + server)
shared/currencies.js Supported currencies (browser + server)
public/ index.html (login), app.html (user app), admin.html
css/style.css Light and dark themes, responsive layout
js/ i18n, api, ui helpers, app, reports, onboarding, admin
scripts/create-admin.js
test/api.test.js
The app runs as a Vercel serverless function (api/index.js → server/app.js) and stores everything in Neon Postgres. Pages, CSS and JS are served from Vercel's CDN (public/). Every push to GitHub redeploys automatically.
| Variable (Vercel → Settings → Environment Variables) | Value |
|---|---|
DATABASE_URL | Neon pooled connection string |
APP_SECRET | 64 hex chars, node -e "console.log(require('crypto').randomBytes(32).toString('hex'))". Keep a copy safe: without it the data can never be decrypted. |
NODE_ENV | production |
ADMIN_USERNAME, ADMIN_PASSWORD | optional: creates the first admin on the first request. Remove ADMIN_PASSWORD afterwards. |
GOOGLE_CLIENT_ID | optional: enables Continue with Google |
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, MAIL_FROM | email sending (see Email setup) |
CRON_SECRET | any long random string; protects the daily month-end report job |
Steps:
finance-baba-project (choose the branch under Git settings if it is not main). Framework preset: Other. Build/output settings come from vercel.json.ADMIN_PASSWORD in Vercel and redeploy.Health check: /api/health.
Put the same DATABASE_URL and the same APP_SECRET in your local .env and run npm start. Your PC and the live site then share one database. Leave DATABASE_URL empty to use a private local database instead.
Anything that runs npm start works too (Render, a VPS, Docker via the included Dockerfile): set DATABASE_URL, APP_SECRET, NODE_ENV=production and TRUST_PROXY=1.
APP_SECRET stored separately from those backups.NODE_ENV=production and TRUST_PROXY=1.APP_SECRET from a secrets manager and back it up separately from the database.data/ folder regularly.