Skip to content
Open
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
22 changes: 22 additions & 0 deletions PasswordlessLogin/manishgupta412/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Mailtrap Email API — Transactional stream (Sending Domains → API Tokens)
MAILTRAP_TOKEN=your-mailtrap-api-token
# Must be an address on a domain verified in Mailtrap
MAIL_FROM_EMAIL=login@yourdomain.com
MAIL_FROM_NAME=Your App

# Public base URL used to build magic links. https:// enables Secure cookies.
APP_URL=http://localhost:3000
PORT=3000

# HMAC key for codes/tokens. Generate with:
# node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"
OTP_SECRET=replace-with-a-long-random-string-at-least-32-chars

# false = only existing users (add with `npm run user:add -- you@example.com`)
# true = create the user on first successful login
AUTO_SIGNUP=false

DATABASE_PATH=./data/app.db

# Set to true only when running behind a reverse proxy that sets X-Forwarded-For
TRUST_PROXY=false
5 changes: 5 additions & 0 deletions PasswordlessLogin/manishgupta412/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
data
.env
*.log
21 changes: 21 additions & 0 deletions PasswordlessLogin/manishgupta412/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Manish Gupta

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
65 changes: 65 additions & 0 deletions PasswordlessLogin/manishgupta412/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Passwordless Login (Express, email code and magic link)

A passwordless login for Node.js apps. Users enter their email and sign in with a **6-digit code** or a **magic link**. Codes and links are hashed, single-use and expire after 10 minutes, a code locks after 5 wrong attempts, and requests are rate limited. Login emails are sent with the Mailtrap Email API.

![Signing in with a 6-digit code](docs/demo.gif)

![Sign-in page](docs/demo-login.png)

## Tech stack

- **Language:** TypeScript (strict mode), Node.js 20 or newer
- **Server:** Express 5, with server-rendered HTML (no frontend framework)
- **Database:** SQLite through `better-sqlite3`
- **Validation:** Zod (environment variables and form input)
- **Email:** the official `mailtrap` SDK (Transactional stream)
- **Tests:** Vitest and Supertest, with a fake mailer and a fake clock

## Run it locally

```bash
cd PasswordlessLogin/manishgupta412
npm install
cp .env.example .env
```

Fill in `.env` (see the next section), then:

```bash
npm run user:add -- you@example.com # needed while AUTO_SIGNUP=false
npm run dev # http://localhost:3000/login
```

Run the tests (no Mailtrap account needed):

```bash
npm test
npm run typecheck
```

## Getting the API key

1. Create a free account at https://mailtrap.io.
2. Go to **Settings, API Tokens** and create a token with access to your sending domain.
3. Put it in `.env` as `MAILTRAP_TOKEN`.
4. Set `MAIL_FROM_EMAIL` to an address on a domain you verified in Mailtrap. For a first try, use `hello@demomailtrap.co` and sign in with your own Mailtrap account email, because the demo domain only delivers to the account owner.
5. Generate the HMAC key for `OTP_SECRET`:

```bash
node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"
```

## Features

- Choose a 6-digit code or a magic link on the login page
- Only the chosen credential is generated, emailed and stored, as an HMAC-SHA256 hash
- Single-use, 10-minute expiry, lock after 5 wrong codes, 60-second resend cooldown with a live timer
- Magic links only show a button on `GET`, so email scanners cannot use them up
- The same page, status and response time for known and unknown emails, so accounts cannot be enumerated
- Hashed server-side sessions, and logs that never contain codes, tokens or links

## Live demo

Not hosted, because it needs a Mailtrap account to send email. The GIF above is a recording of a local run.

Full documentation, flow diagram and security notes: https://github.com/manishgupta412/express-email-otp-login
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added PasswordlessLogin/manishgupta412/docs/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading