logout functionality and documentation

This commit is contained in:
Isuru Bimsara
2026-08-21 14:37:24 +05:30
parent 2a35d86ebf
commit 5d29a8f78f
4 changed files with 106 additions and 20 deletions
+2 -3
View File
@@ -56,8 +56,8 @@ POST: http://localhost:3070/api/auth/login
"email": "sathira@niolla.lk", "email": "sathira@niolla.lk",
"firstName": "Jhon", "firstName": "Jhon",
"lastName": "Doe", "lastName": "Doe",
"role": "System Developer", "accountType": "admin",
"accountType": "admin" "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9......"
} }
} }
``` ```
@@ -90,7 +90,6 @@ No Body
"firstName": "Sathira", "firstName": "Sathira",
"lastName": "Sri Sathsara", "lastName": "Sri Sathsara",
"email": "sathira@niolla.lk", "email": "sathira@niolla.lk",
"role": "System Developer",
"accountType": "admin", "accountType": "admin",
"iat": 1778865265, "iat": 1778865265,
"exp": 1778868865, "exp": 1778868865,
+49 -7
View File
@@ -18,7 +18,9 @@ emailVerifiedAt = null
POST: http://localhost:3070/api/user POST: http://localhost:3070/api/user
``` ```
**Request Body** **Request Body customer**
accontType = customer and bussiness_customer
```json ```json
{ {
@@ -26,6 +28,10 @@ POST: http://localhost:3070/api/user
"lastName": "Bimsara", "lastName": "Bimsara",
"email": "ibimsara00@gmail.com", "email": "ibimsara00@gmail.com",
"password": "Hello@12346" "password": "Hello@12346"
"accountType": "customer",
"address": "Colombo, Sri Lanka",
"phoneNumber": "0771234567"
} }
``` ```
@@ -45,21 +51,20 @@ POST: http://localhost:3070/api/user
} }
``` ```
After registration, the user receives an email containing a verification link. After registration, the user receives an email containing a verification link.
```
#### Verify Email #### Verify Email
Verifies the customer's email using the raw verification token received by email. Verifies the customer's email using the raw verification token received by email.
The backend hashes the received token and compares the resulting hash with the `tokenHash` stored in the `email_verifications` table.
The token must: The token must:
```text ```text
Exist in the database store in redis and expire token
Not have been used
Not have expired
``` ```
**Endpoint** **Endpoint**
@@ -107,7 +112,44 @@ usedAt = <current date and time>
This prevents the same verification token from being successfully used again. This prevents the same verification token from being successfully used again.
--- #### Get user's details
**Endpoint**
```
GET: http://localhost:3070/api/profile
```
**Respond**
```json
{
"success": true,
"message": "User profile retrieved successfully",
"data": {
"user": {
"id": "usr_572gtlpi",
"firstName": "Isuru",
"lastName": "Bimsara",
"email": "ibimsara00@gmail.com",
"accountType": "customer",
"accountStatus": "ACTIVE",
"emailVerifiedAt": "2026-08-20T16:26:04.000Z",
"passwordChangedAt": "2026-08-21T05:29:16.000Z",
"createdAt": "2026-08-20T16:25:30.000Z",
"updatedAt": "2026-08-21T05:29:16.000Z"
},
"accountDetails": {
"customer_id": "cust_c8avqwbc",
"user_id": "usr_572gtlpi",
"address": "Colombo, Sri Lanka",
"phoneNumber": "0771234567",
"createdAt": "2026-08-20T16:25:31.000Z",
"updatedAt": "2026-08-20T16:25:31.000Z"
}
}
}
```
#### Get All Users #### Get All Users
+52 -7
View File
@@ -377,12 +377,57 @@ exports.resetPassword = async (req, res) => {
// Logout: Clear the JWT cookie // Logout: Clear the JWT cookie
exports.logout = (req, res) => { exports.logout = async (req, res) => {
res.clearCookie("access_token", { try {
httpOnly: true, // 1. Get refresh token from cookie
secure: process.env.NODE_ENV === "production", const refreshToken = req.cookies?.refresh_token;
sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax",
});
res.json({ success: true, message: "Logged out successfully" }); // 2. If refresh token exists, find its session
if (refreshToken) {
const session = validateRefreshSession(refreshToken);
// 3. Delete refresh session from server RAM
if (session) {
deleteRefreshSession(session.sessionId);
console.log(
`Refresh session deleted: ${session.sessionId}`
);
}
}
// 4. Clear access token cookie
res.clearCookie("access_token", {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite:
process.env.NODE_ENV === "production"
? "None"
: "Lax",
});
// 5. Clear refresh token cookie
res.clearCookie("refresh_token", {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite:
process.env.NODE_ENV === "production"
? "None"
: "Lax",
});
// 6. Send response
return res.status(200).json({
success: true,
message: "Logged out successfully",
});
} catch (error) {
console.error("LOGOUT ERROR:", error);
return res.status(500).json({
success: false,
message: "Failed to logout",
});
}
}; };
+1 -1
View File
@@ -13,7 +13,7 @@ const jwt = require("jsonwebtoken");
require("dotenv").config(); require("dotenv").config();
const JWT_SECRET = process.env.JWT_SECRET || "your_jwt_secret_key"; const JWT_SECRET = process.env.JWT_SECRET || "your_jwt_secret_key";
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || "1d"; // token validity const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || "15m"; // token validity
const REFRESH_TOKEN_SECRET = process.env.REFRESH_TOKEN_SECRET || "your_refresh_token_secret_key"; const REFRESH_TOKEN_SECRET = process.env.REFRESH_TOKEN_SECRET || "your_refresh_token_secret_key";
const REFRESH_TOKEN_DAYS = process.env.REFRESH_TOKEN_DAYS || "7d"; // refresh token validity const REFRESH_TOKEN_DAYS = process.env.REFRESH_TOKEN_DAYS || "7d"; // refresh token validity