Skip to content

Commit b9e73b7

Browse files
committed
feat: Implement Two-Factor Authentication (2FA) functionality
- Added support for Two-Factor Authentication (2FA) using TOTP. - Introduced new endpoints for 2FA setup, verification, enabling, and disabling. - Updated user model to include fields for 2FA secret and recovery codes. - Enhanced login process to require 2FA verification if enabled. - Integrated QR code generation for 2FA setup and added related documentation. - Updated README and Swagger documentation to reflect new 2FA features.
1 parent 88d1f78 commit b9e73b7

File tree

17 files changed

+2064
-119
lines changed

17 files changed

+2064
-119
lines changed

README.md

Lines changed: 181 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,80 @@
11
# Authentication API
22

3-
A modern, production-ready Go REST API for authentication and authorization, featuring social login, email verification, JWT, and Redis integration.
3+
A modern, production-ready Go REST API for authentication and authorization, featuring social login, email verification, JWT, Two-Factor Authentication (2FA), and Redis integration.
44

55
---
66

77
## 🚀 Features
88
- Secure user registration & login (JWT access/refresh tokens)
9+
- **Two-Factor Authentication (2FA) with TOTP and recovery codes**
910
- Social login: Google, Facebook, GitHub
1011
- Email verification & password reset
1112
- Role-based access control (middleware)
1213
- Redis for token/session management
1314
- Dockerized for local development & deployment
1415
- Unit & integration tests
1516
- **Interactive Swagger API documentation**
17+
- Development and production Docker configurations
1618

1719
## 🗂️ Project Structure
1820
```
1921
cmd/api/main.go # Entry point
20-
internal/ # Core logic (auth, user, social, email, middleware, db)
21-
pkg/ # Models, DTOs, errors, JWT helpers
22-
.env # Environment variables
23-
Dockerfile, docker-compose.yml, dev.sh, dev.bat
22+
internal/ # Core logic
23+
├── auth/ # Authentication handlers
24+
├── user/ # User management
25+
├── social/ # Social authentication (OAuth2)
26+
├── twofa/ # Two-Factor Authentication
27+
├── email/ # Email verification & password reset
28+
├── middleware/ # JWT auth middleware
29+
├── database/ # Database connection & migrations
30+
├── redis/ # Redis connection & session management
31+
├── config/ # Configuration management
32+
└── util/ # Utility functions
33+
pkg/ # Shared packages
34+
├── models/ # Database models
35+
├── dto/ # Data Transfer Objects
36+
├── errors/ # Custom error types
37+
└── jwt/ # JWT utilities
38+
docs/ # API documentation
39+
├── swagger.json # Generated Swagger spec
40+
├── swagger.yaml # Generated Swagger spec
41+
├── docs.go # Generated Swagger docs
42+
├── README.md # Documentation overview
43+
├── ARCHITECTURE.md # System architecture
44+
└── API.md # API reference
45+
.env # Environment variables
46+
.github/ # GitHub templates and workflows
47+
├── ISSUE_TEMPLATE/ # Issue templates
48+
└── workflows/ # CI/CD workflows (if any)
49+
Dockerfile # Production Docker image
50+
Dockerfile.dev # Development Docker image
51+
docker-compose.yml # Production Docker Compose
52+
docker-compose.dev.yml # Development Docker Compose
53+
Makefile # Build and development commands
54+
test_api.sh # API testing script
55+
.air.toml # Air configuration for hot reload
56+
dev.sh, dev.bat # Development startup scripts
57+
CONTRIBUTING.md # Contribution guidelines
58+
CODE_OF_CONDUCT.md # Code of conduct
59+
SECURITY.md # Security policy
60+
LICENSE # MIT License
2461
```
2562

2663
## 📖 API Documentation (Swagger)
2764
After starting the server, access the interactive API docs at:
2865

2966
- [http://localhost:8080/swagger/index.html](http://localhost:8080/swagger/index.html)
3067

31-
You can try out all endpoints, including social logins, directly from the browser.
68+
You can try out all endpoints, including social logins and 2FA operations, directly from the browser.
3269

3370
## 🔄 Regenerating Swagger Documentation
3471
If you make changes to your API routes or annotations, regenerate the Swagger docs with:
3572

73+
```bash
74+
make swag-init
3675
```
76+
or
77+
```bash
3778
swag init -g cmd/api/main.go -o docs
3879
```
3980

@@ -47,6 +88,7 @@ swag init -g cmd/api/main.go -o docs
4788
- Windows: `dev.bat`
4889
- Linux/Mac: `./dev.sh`
4990
4. API available at http://localhost:8080
91+
5. Swagger docs at http://localhost:8080/swagger/index.html
5092

5193
## 🛠️ Manual Setup
5294
1. Create PostgreSQL DB & update `.env`
@@ -81,17 +123,36 @@ The following `make` commands are available for development, testing, building,
81123

82124
> **Tip:** You can also run `make help` to see this list in your terminal.
83125
84-
## 🔑 API Endpoints (Summary)
85-
- `POST /register` — Register
86-
- `POST /login` — Login
87-
- `POST /refresh-token`Refresh JWT
88-
- `POST /forgot-password`Request password reset
89-
- `POST /reset-password`Reset password
126+
## 🔑 API Endpoints
127+
128+
### Authentication
129+
- `POST /register`User registration
130+
- `POST /login`User login (with 2FA support)
131+
- `POST /refresh-token`Refresh JWT tokens
90132
- `GET /verify-email` — Email verification
91-
- Social login: `/auth/{provider}/login` & `/callback`
92-
- `GET /profile` — User profile (protected)
133+
- `POST /forgot-password` — Request password reset
134+
- `POST /reset-password` — Reset password with token
135+
136+
### Two-Factor Authentication (2FA)
137+
- `POST /2fa/generate` — Generate 2FA secret and QR code (protected)
138+
- `POST /2fa/verify-setup` — Verify initial 2FA setup (protected)
139+
- `POST /2fa/enable` — Enable 2FA and get recovery codes (protected)
140+
- `POST /2fa/disable` — Disable 2FA (protected)
141+
- `POST /2fa/login-verify` — Verify 2FA code during login (public)
142+
- `POST /2fa/recovery-codes` — Generate new recovery codes (protected)
93143

94-
## 📦 API Response Example
144+
### Social Authentication
145+
- `GET /auth/google/login` — Initiate Google OAuth2 login
146+
- `GET /auth/google/callback` — Google OAuth2 callback
147+
- `GET /auth/facebook/login` — Initiate Facebook OAuth2 login
148+
- `GET /auth/facebook/callback` — Facebook OAuth2 callback
149+
- `GET /auth/github/login` — Initiate GitHub OAuth2 login
150+
- `GET /auth/github/callback` — GitHub OAuth2 callback
151+
152+
### User Management
153+
- `GET /profile` — Get user profile (protected)
154+
155+
## 📦 API Response Format
95156
**Success:**
96157
```json
97158
{
@@ -108,52 +169,132 @@ The following `make` commands are available for development, testing, building,
108169
```
109170

110171
## 🔒 Authentication Flow
111-
- Register/login returns JWT access & refresh tokens
112-
- Access token in `Authorization: Bearer <token>` header
113-
- Refresh token endpoint issues new access/refresh tokens
114-
- Social login redirects to provider, then back to `/callback`
172+
173+
### Standard Authentication
174+
1. Register/login returns JWT access & refresh tokens
175+
2. Access token in `Authorization: Bearer <token>` header
176+
3. Refresh token endpoint issues new access/refresh tokens
177+
178+
### Two-Factor Authentication Flow
179+
1. User enables 2FA via `/2fa/generate`, `/2fa/verify-setup`, and `/2fa/enable`
180+
2. During login, if 2FA is enabled, a temporary token is returned
181+
3. User provides TOTP code or recovery code via `/2fa/login-verify`
182+
4. Final JWT tokens are issued upon successful 2FA verification
183+
184+
### Social Authentication Flow
185+
1. Redirect to provider login endpoint (e.g., `/auth/google/login`)
186+
2. User authorizes with social provider
187+
3. Provider redirects back to callback endpoint
188+
4. JWT tokens are issued for authenticated user
115189

116190
## 🧪 Testing
191+
192+
### Automated Testing
117193
- Run all tests: `make test` or `go test ./...`
118194
- Coverage: Unit & integration tests for core logic and endpoints
119195

120-
## 🤝 Contributing
121-
Pull requests and issues are welcome! Please open an issue to discuss changes or improvements.
196+
### Manual API Testing
197+
- Use the provided test script: `./test_api.sh`
198+
- Test basic authentication flows and error handling
199+
- Interactive testing via Swagger UI at `/swagger/index.html`
122200

123-
## 🛡️ Security
124-
If you discover a vulnerability, please open an issue or contact the maintainer directly.
201+
## 🐳 Docker Configuration
125202

126-
## ⚙️ Environment Variables (example)
203+
### Development Environment
204+
```bash
205+
# Start development environment with hot reload
206+
make docker-dev
207+
# or
208+
./dev.sh # Linux/Mac
209+
dev.bat # Windows
210+
```
211+
212+
### Production Environment
213+
```bash
214+
# Build and start production containers
215+
make docker-compose-up
216+
# or
217+
docker-compose up -d --build
127218
```
128-
# For Docker Compose:
129-
DB_HOST=postgres
130-
DB_PORT=5432
131-
REDIS_ADDR=redis:6379
132219

133-
# For manual/local run:
134-
# DB_HOST=localhost
135-
# DB_PORT=5432
136-
# REDIS_ADDR=localhost:6379
220+
## ⚙️ Environment Variables
137221

222+
### Required Configuration
223+
```bash
224+
# Database Configuration
225+
DB_HOST=localhost # postgres (for Docker)
226+
DB_PORT=5432
138227
DB_USER=your_db_user
139228
DB_PASSWORD=your_db_password
140229
DB_NAME=auth_db
230+
231+
# Redis Configuration
232+
REDIS_ADDR=localhost:6379 # redis:6379 (for Docker)
233+
234+
# JWT Configuration
141235
JWT_SECRET=supersecretjwtkey
236+
ACCESS_TOKEN_EXPIRATION_MINUTES=15
237+
REFRESH_TOKEN_EXPIRATION_HOURS=720
238+
239+
# Email Configuration
142240
EMAIL_HOST=smtp.example.com
241+
EMAIL_PORT=587
143242
EMAIL_USERNAME=your_email@example.com
243+
EMAIL_PASSWORD=your_email_password
244+
245+
# Social Authentication (OAuth2)
144246
GOOGLE_CLIENT_ID=your_google_client_id
145-
# ...etc
247+
GOOGLE_CLIENT_SECRET=your_google_client_secret
248+
FACEBOOK_CLIENT_ID=your_facebook_client_id
249+
FACEBOOK_CLIENT_SECRET=your_facebook_client_secret
250+
GITHUB_CLIENT_ID=your_github_client_id
251+
GITHUB_CLIENT_SECRET=your_github_client_secret
252+
253+
# Server Configuration
254+
PORT=8080
146255
```
147256

148-
## 🧩 Dependencies
149-
- Gin, GORM, PostgreSQL, Redis, JWT, OAuth2, Viper, godotenv, validator, mail.v2
257+
### Docker vs Local Development
258+
For Docker Compose, use service names:
259+
- `DB_HOST=postgres`
260+
- `REDIS_ADDR=redis:6379`
261+
262+
For local development, use localhost:
263+
- `DB_HOST=localhost`
264+
- `REDIS_ADDR=localhost:6379`
265+
266+
## 🧩 Key Dependencies
267+
- **Web Framework**: Gin
268+
- **Database**: GORM + PostgreSQL
269+
- **Caching**: Go-Redis + Redis
270+
- **Authentication**: JWT, OAuth2
271+
- **Configuration**: Viper, godotenv
272+
- **Validation**: go-playground/validator
273+
- **Email**: gopkg.in/mail.v2
274+
- **2FA**: pquerna/otp, skip2/go-qrcode
275+
- **Documentation**: Swaggo/Swag
276+
- **Development**: Air (hot reload)
277+
278+
## 🧪 Development Workflow
279+
1. `make setup` — Install dependencies and tools
280+
2. `make dev` — Start development server with hot reload
281+
3. `make test` — Run tests during development
282+
4. `make fmt` — Format code before committing
283+
5. `make lint` — Check code quality
284+
6. `./test_api.sh` — Test API endpoints manually
285+
286+
## 🤝 Contributing
287+
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
288+
289+
## 🛡️ Security
290+
Please read [SECURITY.md](SECURITY.md) for information about reporting security vulnerabilities.
150291

151-
## 🧪 Development Commands
152-
- `make dev` — Hot reload
153-
- `make test` — Run tests
154-
- `make build` — Build binary
292+
## 📚 Documentation
293+
- [Architecture Documentation](docs/ARCHITECTURE.md)
294+
- [API Reference](docs/API.md)
295+
- [Implementation Phases](docs/implementation_phases/)
155296

156297
---
157298

158299
## 📄 License
159-
MIT
300+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

cmd/api/main.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/gjovanovicst/auth_api/internal/middleware"
1515
"github.com/gjovanovicst/auth_api/internal/redis"
1616
"github.com/gjovanovicst/auth_api/internal/social"
17+
"github.com/gjovanovicst/auth_api/internal/twofa"
1718
"github.com/gjovanovicst/auth_api/internal/user"
1819
swaggerFiles "github.com/swaggo/files"
1920
ginSwagger "github.com/swaggo/gin-swagger"
@@ -66,8 +67,10 @@ func main() {
6667
emailService := email.NewService()
6768
userService := user.NewService(userRepo, emailService)
6869
socialService := social.NewService(userRepo, socialRepo)
70+
twofaService := twofa.NewService(userRepo)
6971
userHandler := user.NewHandler(userService)
7072
socialHandler := social.NewHandler(socialService)
73+
twofaHandler := twofa.NewHandler(twofaService)
7174

7275
// Setup Gin Router
7376
r := gin.Default()
@@ -81,6 +84,8 @@ func main() {
8184
public.POST("/forgot-password", userHandler.ForgotPassword)
8285
public.POST("/reset-password", userHandler.ResetPassword)
8386
public.GET("/verify-email", userHandler.VerifyEmail)
87+
// 2FA login verification (public because it needs temp token)
88+
public.POST("/2fa/login-verify", twofaHandler.VerifyLogin)
8489
}
8590

8691
// Social authentication routes
@@ -103,8 +108,14 @@ func main() {
103108
protected := r.Group("/")
104109
protected.Use(middleware.AuthMiddleware())
105110
{
106-
protected.GET("/profile", userHandler.GetProfile) // Example protected route
107-
// Add other protected routes here
111+
protected.GET("/profile", userHandler.GetProfile)
112+
113+
// 2FA management routes
114+
protected.POST("/2fa/generate", twofaHandler.Generate2FA)
115+
protected.POST("/2fa/verify-setup", twofaHandler.VerifySetup)
116+
protected.POST("/2fa/enable", twofaHandler.Enable2FA)
117+
protected.POST("/2fa/disable", twofaHandler.Disable2FA)
118+
protected.POST("/2fa/recovery-codes", twofaHandler.GenerateRecoveryCodes)
108119
}
109120

110121
// Add Swagger UI endpoint
@@ -116,4 +127,4 @@ func main() {
116127
if err := r.Run(fmt.Sprintf(":%s", port)); err != nil {
117128
log.Fatalf("Server failed to start: %v", err)
118129
}
119-
}
130+
}

0 commit comments

Comments
 (0)