Skip to content
Merged
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
11 changes: 0 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,19 +248,8 @@ oauth2: {
- **onSuccess**: Callback executed on successful OAuth2 authentication, This is where user registration/creation logic should be implemented
- **onFailure**: Callback executed on OAuth2 authentication failure
- **defaultRole**: Default role assigned to new users.
- **setRefreshCookie**: Set refresh token as HTTP-only cookie.
- **appendTokensInRedirect**: Include tokens in redirect URL.
- **providers**: Supported providers (e.g., Google, GitHub).

```

- **enabled**: Enables cookie support.
- **name**: Cookie name for refresh token.
- **httpOnly**: Prevents client-side JavaScript access.
- **secure**: Only send over HTTPS.
- **sameSite**: CSRF protection setting.
- **maxAge**: Cookie expiration time.
- **path**: Cookie path.

### **Two-Factor Authentication**

Expand Down
224 changes: 150 additions & 74 deletions docs/nestjs_usage.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,116 @@
# PassportJS Authentication Library
# NestJS Usage with Auth-Core

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.
Auth-Core provides seamless authentication integration for **NestJS** applications, supporting **JWT**, **Session-based**, and **OAuth 2.0** authentication — all configurable through a unified API.

---

## Features

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

---

## Installation

Install the library via npm:
Install Auth-Core via npm:

```bash
npm install @flycatch/auth-core
```

---

## Usage
## Configuration in NestJS

### Configuration for NestJS
### 1. Configure Auth-Core in `main.ts`

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

```bash
npm install auth-core @nestjs/auth-core
```typescript
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { config } from "@flycatch/auth-core";
import bcrypt from "bcrypt";

async function bootstrap() {
const app = await NestFactory.create(AppModule);

const userRepository = {
async find(email: string) {
return {
id: "123",
email,
username: "exampleUser",
grants: ["read_user"],
is2faEnabled: false,
};
},
};

app.use(
config({
jwt: {
enabled: true,
secret: "my_jwt_secret",
expiresIn: "1h",
refresh: true,
prefix: "/auth/jwt",
},
session: {
enabled: true,
prefix: "/auth/session",
secret: "my_session_secret",
resave: false,
saveUninitialized: true,
cookie: { secure: false, maxAge: 60000 },
},
oauth2: {
enabled: true,
baseURL: "http://localhost:3000",
prefix: "/auth",
successRedirect: "http://localhost:3000/oauth-success",
failureRedirect: "http://localhost:3000/oauth-failure",
providers: {
google: {
clientID: "GOOGLE_CLIENT_ID",
clientSecret: "GOOGLE_CLIENT_SECRET",
callbackURL: "/auth/google/callback",
scope: ["profile", "email"],
},
},
},
userService: {
loadUser: async (email) => userRepository.find(email),
createUser: async (profile) => ({
id: "new-user-id",
email: profile.email,
username: profile.username,
grants: ["ROLE_USER"],
}),
},
passwordChecker: async (inputPassword, storedPassword) =>
bcrypt.compare(inputPassword, storedPassword),
logs: true,
})
);

await app.listen(3000);
console.log(`🚀 Server running at http://localhost:3000`);
}

bootstrap();
```

#### Create an `AuthGuard`
---

### 2. Create a Custom `AuthGuard`

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

```typescript
import {
Expand All @@ -45,7 +119,7 @@ import {
ExecutionContext,
UnauthorizedException,
} from "@nestjs/common";
import authCore from "@flycatch/auth-core"; // Import the library
import { verify } from "@flycatch/auth-core";

@Injectable()
export class AuthGuard implements CanActivate {
Expand All @@ -60,11 +134,11 @@ export class AuthGuard implements CanActivate {
new UnauthorizedException(err.message || "Unauthorized")
);
}
resolve(true); // Authentication passed
resolve(true);
};

try {
const verifyMiddleware = authCore.verify();
const verifyMiddleware = verify();
verifyMiddleware(req, res, next);
} catch (error: any) {
reject(new UnauthorizedException("Authentication error"));
Expand All @@ -74,9 +148,13 @@ export class AuthGuard implements CanActivate {
}
```

#### Controller Example
> ✅ You can also pass permissions to `verify()` — e.g. `verify("admin_access")` — for role-based control.

Define a controller to protect routes in `app.controller.ts`:
---

### 3. Protect Routes in Your Controller

Use the custom guard to protect any route.

```typescript
import { Controller, Get, UseGuards, Req } from "@nestjs/common";
Expand All @@ -87,98 +165,96 @@ export class UserController {
@Get("/")
@UseGuards(AuthGuard)
getUser(@Req() req) {
return { user: req.user };
return { message: "Access granted", user: req.user };
}
}
```

#### Integrating Authentication Configuration in `main.ts`
---

### Set up authentication in your NestJS entry point:
### 4. Example with Role-Based Access

If your app uses permissions or roles (e.g., `"admin"`), extend your guard:

```typescript
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import auth from "auth-core"; // Import the library
@Injectable()
export class RoleGuard implements CanActivate {
constructor(private requiredRole: string) {}

async function bootstrap() {
const app = await NestFactory.create(AppModule);
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
const res = context.switchToHttp().getResponse();

auth.config({
jwt: {
enabled: true,
refresh: true,
config: { secret: "your_jwt_secret" },
},
session: {
enabled: true,
secret: "your_session_secret",
},
google: {
enabled: true,
clientID: "your_google_client_id",
clientSecret: "your_google_client_secret",
callbackURL: "http://localhost:3000/auth/google/callback",
},
});
return new Promise((resolve, reject) => {
const next = (err?: any) => {
if (err) return reject(new UnauthorizedException(err.message));
if (!req.user?.grants?.includes(this.requiredRole)) {
return reject(new UnauthorizedException("Access denied"));
}
resolve(true);
};

app.use(auth.initialize()); // Initialize authentication middleware
await app.listen(3000);
verify()(req, res, next);
});
}
}

bootstrap();
```

---

## Authentication Methods Supported

1. **JWT Authentication**
Usage:

- Provides token-based authentication with access and refresh tokens.
- Tokens are validated using the `auth.verify()` middleware.
```typescript
@Controller("admin")
export class AdminController {
@Get("/")
@UseGuards(new RoleGuard("admin"))
getAdminDashboard(@Req() req) {
return { message: "Admin Access", user: req.user };
}
}
```

2. **Session-based Authentication**
---

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

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

---

## Testing Authentication

### Protected Route
### JWT-Protected Route

Once configured, access a protected route:
```bash
curl -X GET http://localhost:3000/user \
-H "Authorization: Bearer <your_jwt_token>"
```

#### NestJS:
### OAuth 2.0 Login

```bash
curl -X GET http://localhost:3000/user -H "Authorization: Bearer <your_jwt_token>"
http://localhost:3000/auth/google
```

### Google OAuth Login

1. Navigate to: `http://localhost:3000/auth/google`
2. Authenticate via Google.
3. Access your user details from `/user`.
After successful login, user data is returned from `/user`.

---

## Contributing

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

---

## License

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

---

## [Back](../README.md)
## [Back to Main README](../README.md)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@flycatch/auth-core",
"version": "1.2.0",
"version": "1.3.0",
"description": "A unified authentication module for Express.js, NestJS frameworks, supporting JWT, session-based, and Google OAuth login.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
2 changes: 0 additions & 2 deletions src/interfaces/config.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@ export interface OAuth2Config {
successRedirect: string; // Redirect URL on successful login
failureRedirect: string; // Redirect URL on failed login
defaultRole?: string; // Default role assigned to new users
setRefreshCookie?: boolean; // Store refresh token as an HTTP cookie
appendTokensInRedirect?: boolean; // Append tokens in redirect URL

/**
* Callback executed on successful OAuth2 authentication
Expand Down
Loading