Skip to content

Commit 0fc6203

Browse files
feat(examples): add database-conns POC for live-tenant signup and change-password
Signed re-add of the database-conns example that previously entered the branch via an unsigned upstream merge lineage. Content matches the validated PR tree.
1 parent 9625669 commit 0fc6203

6 files changed

Lines changed: 216 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
AUTH0_DOMAIN=your-tenant.auth0.com
2+
AUTH0_CLIENT_ID=your_client_id
3+
AUTH0_CLIENT_SECRET=your_client_secret
4+
AUTH0_DB_CONNECTION=Username-Password-Authentication
5+
APP_BASE_URL=http://localhost:3000
6+
PORT=3000

examples/database-conns/README.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Database Connections POC Example
2+
3+
This is a manual harness for live-tenant testing of `signUp` and `changePassword` database connection operations with Auth0.
4+
5+
## Prerequisites
6+
7+
- An Auth0 tenant with a database connection enabled on the app
8+
- Signup enabled on the connection (or expect documented signup-disabled behavior)
9+
- The client configured as either a confidential app (with client secret) or public app as configured
10+
- Node.js and npm installed
11+
12+
## Setup
13+
14+
1. Copy `.env.example` to `.env` and fill in your Auth0 tenant credentials:
15+
```bash
16+
cp .env.example .env
17+
```
18+
19+
2. Install workspace dependencies at the repo root:
20+
```bash
21+
npm install
22+
```
23+
24+
3. Build the auth0-auth-js and auth0-server-js packages first to ensure the example resolves the new database connection surface from dist:
25+
```bash
26+
npm run build --workspace=packages/auth0-auth-js
27+
npm run build --workspace=packages/auth0-server-js
28+
```
29+
30+
4. Install the example dependencies:
31+
```bash
32+
npm install --workspace=examples/database-conns
33+
```
34+
35+
## Running
36+
37+
```bash
38+
npm start --workspace=examples/database-conns
39+
```
40+
41+
The app will start on the port specified in your `.env` (default: `http://localhost:3000`).
42+
43+
## Testing
44+
45+
### Sign Up
46+
47+
Test user registration:
48+
49+
```bash
50+
curl -X POST localhost:3000/signup \
51+
-H 'content-type: application/json' \
52+
-d '{"email":"new@example.com","password":"Str0ng-pw!"}'
53+
```
54+
55+
Expected success response:
56+
```json
57+
{
58+
"ok": true,
59+
"user": {
60+
"id": "...",
61+
"email": "new@example.com",
62+
"emailVerified": false
63+
}
64+
}
65+
```
66+
67+
Expected error when re-running with the same email:
68+
```json
69+
{
70+
"ok": false,
71+
"code": "signup_error",
72+
"message": "...",
73+
"cause": { "error": "..." }
74+
}
75+
```
76+
77+
### Change Password
78+
79+
Test password reset request:
80+
81+
```bash
82+
curl -X POST localhost:3000/change-password \
83+
-H 'content-type: application/json' \
84+
-d '{"email":"new@example.com"}'
85+
```
86+
87+
Expected success response:
88+
```json
89+
{
90+
"ok": true,
91+
"message": "We've just sent you an email to reset your password."
92+
}
93+
```
94+
95+
A password reset email will be sent to the specified email address from your Auth0 tenant.
96+
97+
## Investigation Notes
98+
99+
This POC is the live-tenant check that closes the signup success-rate investigation. When running the tests above, capture observed status codes and response codes for:
100+
101+
- Existing user signup attempt (expect 4xx validation error)
102+
- Weak password signup attempt (expect 4xx validation error)
103+
- Signup with disabled connection (expect 4xx validation error)
104+
105+
These should all be expected validation 4xx responses, not a defect. Any 5xx or unexpected behavior indicates a platform issue.
106+
107+
## Implementation Details
108+
109+
The example:
110+
- Uses a simple no-op state store for the `ServerClient` (database operations never read or write session state)
111+
- Catches `SignUpError` and `ChangePasswordError` and surfaces them with appropriate HTTP status codes
112+
- Reads plain text responses from the change-password endpoint
113+
114+
See the source files for implementation details.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "example-database-conns",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"start": "tsx src/index.ts --project tsconfig.json",
8+
"build": "tsc --project tsconfig.json"
9+
},
10+
"devDependencies": {
11+
"@types/express": "^5.0.1",
12+
"tsx": "^4.19.2",
13+
"typescript": "~5.8.3"
14+
},
15+
"dependencies": {
16+
"@auth0/auth0-server-js": "*",
17+
"dotenv": "^16.4.7",
18+
"express": "^5.1.0"
19+
}
20+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'dotenv/config';
2+
import { ServerClient } from '@auth0/auth0-server-js';
3+
4+
export const connection = process.env.AUTH0_DB_CONNECTION!;
5+
6+
export const auth0 = new ServerClient({
7+
domain: process.env.AUTH0_DOMAIN!,
8+
clientId: process.env.AUTH0_CLIENT_ID!,
9+
clientSecret: process.env.AUTH0_CLIENT_SECRET!,
10+
// ServerClient requires state and transaction stores at construction. The database operations
11+
// (signUp / changePassword) never read or write them, so no-op stores are sufficient
12+
// for this POC. A real app uses StatelessStateStore / StatefulStateStore and CookieTransactionStore.
13+
stateStore: {
14+
set: async () => {},
15+
get: async () => undefined,
16+
delete: async () => {},
17+
} as any,
18+
transactionStore: {
19+
create: async () => 'noop',
20+
read: async () => undefined,
21+
delete: async () => {},
22+
} as any,
23+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import express from 'express';
2+
import { auth0, connection } from './auth0.js';
3+
import { SignUpError, ChangePasswordError } from '@auth0/auth0-server-js';
4+
5+
const app = express();
6+
app.use(express.json());
7+
8+
// POST /signup { email, password }
9+
app.post('/signup', async (req, res) => {
10+
try {
11+
const result = await auth0.database.signUp({
12+
email: req.body.email,
13+
password: req.body.password,
14+
connection,
15+
});
16+
res.json({ ok: true, user: result }); // result.id normalized
17+
} catch (err) {
18+
if (err instanceof SignUpError) {
19+
res.status(400).json({ ok: false, code: err.code, message: err.message, cause: err.cause });
20+
} else {
21+
res.status(500).json({ ok: false, message: 'unexpected' });
22+
}
23+
}
24+
});
25+
26+
// POST /change-password { email }
27+
app.post('/change-password', async (req, res) => {
28+
try {
29+
const message = await auth0.database.changePassword({ email: req.body.email, connection });
30+
res.json({ ok: true, message }); // plain-text confirmation
31+
} catch (err) {
32+
if (err instanceof ChangePasswordError) {
33+
res.status(400).json({ ok: false, code: err.code, message: err.message });
34+
} else {
35+
res.status(500).json({ ok: false, message: 'unexpected' });
36+
}
37+
}
38+
});
39+
40+
const port = Number(process.env.PORT ?? 3000);
41+
app.listen(port, () => console.log(`database-conns POC on http://localhost:${port}`));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "NodeNext",
5+
"moduleResolution": "NodeNext",
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"skipLibCheck": true,
9+
"outDir": "dist"
10+
},
11+
"include": ["src/**/*.ts"]
12+
}

0 commit comments

Comments
 (0)