Skip to content

Commit 4d0fe27

Browse files
authored
Merge pull request #15 from flycatch/fix/phase-3
fix(oauth): remove security threats, and update cookie config
2 parents 5d8193b + fb9c52e commit 4d0fe27

File tree

5 files changed

+179
-132
lines changed

5 files changed

+179
-132
lines changed

README.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,8 @@ oauth2: {
248248
- **onSuccess**: Callback executed on successful OAuth2 authentication, This is where user registration/creation logic should be implemented
249249
- **onFailure**: Callback executed on OAuth2 authentication failure
250250
- **defaultRole**: Default role assigned to new users.
251-
- **setRefreshCookie**: Set refresh token as HTTP-only cookie.
252-
- **appendTokensInRedirect**: Include tokens in redirect URL.
253251
- **providers**: Supported providers (e.g., Google, GitHub).
254252

255-
```
256-
257-
- **enabled**: Enables cookie support.
258-
- **name**: Cookie name for refresh token.
259-
- **httpOnly**: Prevents client-side JavaScript access.
260-
- **secure**: Only send over HTTPS.
261-
- **sameSite**: CSRF protection setting.
262-
- **maxAge**: Cookie expiration time.
263-
- **path**: Cookie path.
264253

265254
### **Two-Factor Authentication**
266255

docs/nestjs_usage.md

Lines changed: 150 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,116 @@
1-
# PassportJS Authentication Library
1+
# NestJS Usage with Auth-Core
22

3-
A unified authentication solution for **Express.js** and **NestJS** applications. This library supports **JWT**, **Session-based Authentication**, and **Google OAuth**, providing a seamless integration for both frameworks.
3+
Auth-Core provides seamless authentication integration for **NestJS** applications, supporting **JWT**, **Session-based**, and **OAuth 2.0** authentication — all configurable through a unified API.
44

55
---
66

77
## Features
88

9-
- **JWT Authentication** with Access and Refresh Tokens.
10-
- **Session-based Authentication** for persistent user sessions.
11-
- **Google OAuth2 Login** for social authentication.
12-
- Middleware-based verification for secure routes.
13-
- Easy-to-configure for both **Express.js** and **NestJS**.
9+
-**JWT Authentication** with Access and Refresh Tokens
10+
-**Session-based Authentication** for persistent user sessions
11+
-**OAuth 2.0 Login** (Google, GitHub, and custom providers)
12+
-**Two-Factor Authentication (2FA)** support
13+
-**Role and Permission-Based Access Control**
14+
- ✅ Plug-and-play integration with NestJS Guards
1415

1516
---
1617

1718
## Installation
1819

19-
Install the library via npm:
20+
Install Auth-Core via npm:
2021

2122
```bash
2223
npm install @flycatch/auth-core
2324
```
2425

2526
---
2627

27-
## Usage
28+
## Configuration in NestJS
2829

29-
### Configuration for NestJS
30+
### 1. Configure Auth-Core in `main.ts`
3031

31-
#### Install Dependencies
32+
Initialize Auth-Core just like in Express, but within your NestJS bootstrap function.
3233

33-
```bash
34-
npm install auth-core @nestjs/auth-core
34+
```typescript
35+
import { NestFactory } from "@nestjs/core";
36+
import { AppModule } from "./app.module";
37+
import { config } from "@flycatch/auth-core";
38+
import bcrypt from "bcrypt";
39+
40+
async function bootstrap() {
41+
const app = await NestFactory.create(AppModule);
42+
43+
const userRepository = {
44+
async find(email: string) {
45+
return {
46+
id: "123",
47+
email,
48+
username: "exampleUser",
49+
grants: ["read_user"],
50+
is2faEnabled: false,
51+
};
52+
},
53+
};
54+
55+
app.use(
56+
config({
57+
jwt: {
58+
enabled: true,
59+
secret: "my_jwt_secret",
60+
expiresIn: "1h",
61+
refresh: true,
62+
prefix: "/auth/jwt",
63+
},
64+
session: {
65+
enabled: true,
66+
prefix: "/auth/session",
67+
secret: "my_session_secret",
68+
resave: false,
69+
saveUninitialized: true,
70+
cookie: { secure: false, maxAge: 60000 },
71+
},
72+
oauth2: {
73+
enabled: true,
74+
baseURL: "http://localhost:3000",
75+
prefix: "/auth",
76+
successRedirect: "http://localhost:3000/oauth-success",
77+
failureRedirect: "http://localhost:3000/oauth-failure",
78+
providers: {
79+
google: {
80+
clientID: "GOOGLE_CLIENT_ID",
81+
clientSecret: "GOOGLE_CLIENT_SECRET",
82+
callbackURL: "/auth/google/callback",
83+
scope: ["profile", "email"],
84+
},
85+
},
86+
},
87+
userService: {
88+
loadUser: async (email) => userRepository.find(email),
89+
createUser: async (profile) => ({
90+
id: "new-user-id",
91+
email: profile.email,
92+
username: profile.username,
93+
grants: ["ROLE_USER"],
94+
}),
95+
},
96+
passwordChecker: async (inputPassword, storedPassword) =>
97+
bcrypt.compare(inputPassword, storedPassword),
98+
logs: true,
99+
})
100+
);
101+
102+
await app.listen(3000);
103+
console.log(`🚀 Server running at http://localhost:3000`);
104+
}
105+
106+
bootstrap();
35107
```
36108

37-
#### Create an `AuthGuard`
109+
---
110+
111+
### 2. Create a Custom `AuthGuard`
38112

39-
Create a custom guard in `authguard.guard.ts`:
113+
Use Auth-Core’s `verify()` middleware inside a NestJS Guard for route protection.
40114

41115
```typescript
42116
import {
@@ -45,7 +119,7 @@ import {
45119
ExecutionContext,
46120
UnauthorizedException,
47121
} from "@nestjs/common";
48-
import authCore from "@flycatch/auth-core"; // Import the library
122+
import { verify } from "@flycatch/auth-core";
49123

50124
@Injectable()
51125
export class AuthGuard implements CanActivate {
@@ -60,11 +134,11 @@ export class AuthGuard implements CanActivate {
60134
new UnauthorizedException(err.message || "Unauthorized")
61135
);
62136
}
63-
resolve(true); // Authentication passed
137+
resolve(true);
64138
};
65139

66140
try {
67-
const verifyMiddleware = authCore.verify();
141+
const verifyMiddleware = verify();
68142
verifyMiddleware(req, res, next);
69143
} catch (error: any) {
70144
reject(new UnauthorizedException("Authentication error"));
@@ -74,9 +148,13 @@ export class AuthGuard implements CanActivate {
74148
}
75149
```
76150

77-
#### Controller Example
151+
> ✅ You can also pass permissions to `verify()` — e.g. `verify("admin_access")` — for role-based control.
78152
79-
Define a controller to protect routes in `app.controller.ts`:
153+
---
154+
155+
### 3. Protect Routes in Your Controller
156+
157+
Use the custom guard to protect any route.
80158

81159
```typescript
82160
import { Controller, Get, UseGuards, Req } from "@nestjs/common";
@@ -87,98 +165,96 @@ export class UserController {
87165
@Get("/")
88166
@UseGuards(AuthGuard)
89167
getUser(@Req() req) {
90-
return { user: req.user };
168+
return { message: "Access granted", user: req.user };
91169
}
92170
}
93171
```
94172

95-
#### Integrating Authentication Configuration in `main.ts`
173+
---
96174

97-
### Set up authentication in your NestJS entry point:
175+
### 4. Example with Role-Based Access
176+
177+
If your app uses permissions or roles (e.g., `"admin"`), extend your guard:
98178

99179
```typescript
100-
import { NestFactory } from "@nestjs/core";
101-
import { AppModule } from "./app.module";
102-
import auth from "auth-core"; // Import the library
180+
@Injectable()
181+
export class RoleGuard implements CanActivate {
182+
constructor(private requiredRole: string) {}
103183

104-
async function bootstrap() {
105-
const app = await NestFactory.create(AppModule);
184+
async canActivate(context: ExecutionContext): Promise<boolean> {
185+
const req = context.switchToHttp().getRequest();
186+
const res = context.switchToHttp().getResponse();
106187

107-
auth.config({
108-
jwt: {
109-
enabled: true,
110-
refresh: true,
111-
config: { secret: "your_jwt_secret" },
112-
},
113-
session: {
114-
enabled: true,
115-
secret: "your_session_secret",
116-
},
117-
google: {
118-
enabled: true,
119-
clientID: "your_google_client_id",
120-
clientSecret: "your_google_client_secret",
121-
callbackURL: "http://localhost:3000/auth/google/callback",
122-
},
123-
});
188+
return new Promise((resolve, reject) => {
189+
const next = (err?: any) => {
190+
if (err) return reject(new UnauthorizedException(err.message));
191+
if (!req.user?.grants?.includes(this.requiredRole)) {
192+
return reject(new UnauthorizedException("Access denied"));
193+
}
194+
resolve(true);
195+
};
124196

125-
app.use(auth.initialize()); // Initialize authentication middleware
126-
await app.listen(3000);
197+
verify()(req, res, next);
198+
});
199+
}
127200
}
128-
129-
bootstrap();
130201
```
131202

132-
---
133-
134-
## Authentication Methods Supported
135-
136-
1. **JWT Authentication**
203+
Usage:
137204

138-
- Provides token-based authentication with access and refresh tokens.
139-
- Tokens are validated using the `auth.verify()` middleware.
205+
```typescript
206+
@Controller("admin")
207+
export class AdminController {
208+
@Get("/")
209+
@UseGuards(new RoleGuard("admin"))
210+
getAdminDashboard(@Req() req) {
211+
return { message: "Admin Access", user: req.user };
212+
}
213+
}
214+
```
140215

141-
2. **Session-based Authentication**
216+
---
142217

143-
- Securely stores user data in the session.
144-
- Sessions are validated using the `auth.verify()` middleware.
218+
## Supported Authentication Methods
145219

146-
3. **Google OAuth**
147-
- Enables login via Google.
148-
- The library handles redirection, callback, and verification seamlessly.
220+
| Method | Description |
221+
| ------------- | --------------------------------------------------------------- |
222+
| **JWT** | Token-based authentication with access & refresh tokens |
223+
| **Session** | Persistent user sessions stored securely |
224+
| **OAuth 2.0** | Social login via Google, GitHub, or custom providers |
225+
| **2FA** | Optional OTP-based two-factor verification for sensitive logins |
149226

150227
---
151228

152229
## Testing Authentication
153230

154-
### Protected Route
231+
### JWT-Protected Route
155232

156-
Once configured, access a protected route:
233+
```bash
234+
curl -X GET http://localhost:3000/user \
235+
-H "Authorization: Bearer <your_jwt_token>"
236+
```
157237

158-
#### NestJS:
238+
### OAuth 2.0 Login
159239

160240
```bash
161-
curl -X GET http://localhost:3000/user -H "Authorization: Bearer <your_jwt_token>"
241+
http://localhost:3000/auth/google
162242
```
163243

164-
### Google OAuth Login
165-
166-
1. Navigate to: `http://localhost:3000/auth/google`
167-
2. Authenticate via Google.
168-
3. Access your user details from `/user`.
244+
After successful login, user data is returned from `/user`.
169245

170246
---
171247

172248
## Contributing
173249

174-
Contributions are welcome! Fork the repository and create a PR with your changes.
250+
Contributions are welcome! Please fork the repository and submit a pull request.
175251

176252
---
177253

178254
## License
179255

180-
GPL-3.0 License. See the `LICENSE` file for details.
256+
This project is licensed under the **GPL-3.0 License**.
181257

182258
---
183259

184-
## [Back](../README.md)
260+
## [Back to Main README](../README.md)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@flycatch/auth-core",
3-
"version": "1.2.0",
3+
"version": "1.3.0",
44
"description": "A unified authentication module for Express.js, NestJS frameworks, supporting JWT, session-based, and Google OAuth login.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/interfaces/config.interface.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ export interface OAuth2Config {
125125
successRedirect: string; // Redirect URL on successful login
126126
failureRedirect: string; // Redirect URL on failed login
127127
defaultRole?: string; // Default role assigned to new users
128-
setRefreshCookie?: boolean; // Store refresh token as an HTTP cookie
129-
appendTokensInRedirect?: boolean; // Append tokens in redirect URL
130128

131129
/**
132130
* Callback executed on successful OAuth2 authentication

0 commit comments

Comments
 (0)