# Cameras A web interface for discovering and managing Hikvision and Annke IP cameras on your local network. ## Securing the web interface The dashboard and its API are protected by a single admin login. The login is stored in a file, **never** in plain text: the password is hashed with [scrypt](https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback) (random salt, N=65536, r=8, p=1), so it can't be recovered from the file. | Setting | Default | | --- | --- | | `ADMIN_AUTH_FILE` (environment variable, e.g. in `.env.local`) | `./.data/admin.json` | If the file doesn't exist, the app starts **unsecured**: anyone who can reach it can view your cameras and change their logins. To avoid ever running it that way, create the admin file before the first start. ### Create the admin login (recommended) ```bash npm run admin:create ``` It asks for a username and a password (at least 12 characters; typing is hidden, and you confirm it), then writes the file with owner-only permissions (`0600`). Options: ```bash npm run admin:create -- --username admin # only ask for the password npm run admin:create -- --force # replace the existing admin (reset the password) printf '%s\n' "$PW" | npm run admin:create -- --username admin # non-interactive, e.g. provisioning ``` ### Without npm: a Node one-liner Any Node 24+ can produce the same file. The password is read from the terminal without echoing, so it never appears in your shell history or the process list: ```bash (read -rs PW && export PW && umask 077 && mkdir -p .data && node -e ' const c = require("node:crypto"), N = 65536, r = 8, p = 1, salt = c.randomBytes(16); const key = c.scryptSync(process.env.PW, salt, 64, { N, r, p, maxmem: 256 * N * r }); const passwordHash = ["scrypt", N, r, p, salt.toString("base64"), key.toString("base64")].join("$"); console.log(JSON.stringify({ version: 1, username: "admin", passwordHash }, null, 2)); ' > .data/admin.json) ``` The parentheses run it in a subshell, so the password variable and the stricter `umask` end with it. Change `username: "admin"` to taste. Usernames are 1–64 letters, digits, or `. _ @ -`. ### File format ```json { "version": 1, "username": "admin", "passwordHash": "scrypt$65536$8$1$$<64-byte key, base64>" } ``` A file that exists but is malformed stops the app from authenticating anyone rather than quietly turning security off; fix it or delete it. ### Forgot the password? Run `npm run admin:create -- --force` (or delete the file and create it again). Changing the password signs out every existing session. --- This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). ## Getting Started First, run the development server: ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More To learn more about Next.js, take a look at the following resources: - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! ## Deploy on Vercel The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.