0.0.1 • Published 5 months ago
auth-package-vasu-cct v0.0.1
Authentication Package
This package provides authentication functionalities, including user registration, login, and third-party OAuth authentication with GitHub, Google, Microsoft, and Okta. It also supports OTP-based authentication.
Installation & Setup
1. Install Dependencies
npm install auth-package-vasu-cct
2. Define Environment Variables (.env)
Create a .env
file and add the following credentials:
PORT=3000
MONGO_URI="mongodb://localhost:27017/task_10"
JWT_SECRET=YOUR_SECRET_KEY
SESSION_SECRET=YOUR_SESSION_SECRET
GITHUB_CLIENT_ID=YOUR_GITHUB_CLIENT_ID
GITHUB_CLIENT_SECRET=YOUR_GITHUB_CLIENT_SECRET
GITHUB_CALLBACK_URL=http://localhost:3000/auth/github/callback
GOOGLE_CLIENT_ID=YOUR_GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET=YOUR_GOOGLE_CLIENT_SECRET
GOOGLE_REDIRECT_URI=http://localhost:3000/google/callback
MICROSOFT_CLIENT_ID=YOUR_MICROSOFT_CLIENT_ID
MICROSOFT_REDIRECT_URI=http://localhost:3000/auth/microsoft/callback
MICROSOFT_CLIENT_SECRET=YOUR_MICROSOFT_CLIENT_SECRET
OKTA_CLIENT_ID:YOUR_AUTH0_CLIENT_ID;
OKTA_CLIENT_SECRET:YOUR_AUTH0_CLIENT_SECRET;
OKTA_REDIRECT_URI:http://localhost:3000/auth/sso/callback;
OKTA_DOMAIN:YOUR_AUTH0_DOMAIN;
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-email-password
3. Start the Server
npm start
API Endpoints
User Authentication
1. User Registration
POST /register
Request Body:
{
"email": "user@example.com",
"password": "securepassword",
"username": "john_doe"
}
2. User Login
POST /login
Request Body:
{
"email": "user@example.com",
"password": "securepassword"
}
OAuth Authentication
3. GitHub OAuth
Initiate Login:
GET /github
Redirects user to GitHub authentication page.
Callback:
GET /github/callback?code=AUTH_CODE
4. Google OAuth
Initiate Login:
GET /google
Callback:
GET /google/callback?code=AUTH_CODE
5. Microsoft OAuth
Initiate Login:
GET /auth/microsoft
Callback:
GET /auth/microsoft/callback?code=AUTH_CODE
6. SSO Login (Okta)
Initiate Login:
GET /auth/ssologin
Callback:
GET /auth/sso/callback?code=AUTH_CODE
OTP Authentication
7. OTP Login
POST /otplogin
Request Body:
{
"email": "user@example.com",
"password": "securepassword"
}
8. Verify OTP
POST /verify-otp
Request Body:
{
"email": "user@example.com",
"otp": "123456"
}
Usage in Express Application
To use this authentication package in your Express.js app, follow the example below:
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import { githubAuthInitiate, githubAuthCallback } from "package_name";
import { googleAuthInitiate,googleAuthCallback } from "package_name";
import { microsoftAuthInitiate,microsoftAuthCallback } from "package_name";
import { oktaAuthInitiate,oktaAuthCallback } from "package_name";
import {signupHandler,loginHandler} from "package_name";
import { sendEmail } from "package_name";
import { verifyOtpHandler } from "package_name";
dotenv.config();
const app = express();
app.use(express.json());
const PORT = process.env.PORT;
export const authConfig = {
clientId: process.env.GITHUB_CLIENT_ID as string,
clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
redirectUri: process.env.GITHUB_REDIRECT_URI as string,
findUserByGitHubId: async (githubId: number): Promise<IUser | null> => {
return await UserModel.findOne({ githubId });
},
createUser: async (userData: Partial<IUser>): Promise<IUser> => {
const user = new UserModel(userData);
return await user.save();
},
};
export const authemailConfig: Config = {
hashAlgorithm: "crypto",
generateSecureKey: () => "yourCustomKey",
checkUserExist: async (email: string) => {
return await UserModel.findOne({ email }) !== null;
},
createUser: async (userData: any) => {
const newUser = new UserModel(userData);
await newUser.save();
return newUser;
},
createAuthRecord: async (authData: any) => {
const newAuth = new Auth(authData);
await newAuth.save();
console.log("Auth record created:", newAuth);
},
getUserByEmail: async (email: string) => {
return await UserModel.findOne({ email });
},
getAuthRecord: async (id: string) => {
return await Auth.findOne({ userId: id });
},
sendEmail: sendEmail,
};
export const authGoogleConfig = {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
redirectUri: process.env.GOOGLE_REDIRECT_URI as string,
findUserByGoogleId: async (googleId: string): Promise<IUser | null> => {
return await UserModel.findOne({ googleId });
},
createUser: async (userData: Partial<IUser>): Promise<IUser> => {
const user = new UserModel(userData);
return await user.save();
},
};
export const authMicrosftConfig = {
clientId: process.env.MICROSOFT_CLIENT_ID as string,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET as string,
redirectUri: process.env.MICROSOFT_REDIRECT_URI as string,
findUserByMicrosoftId: async (microsoftId: string): Promise<IUser | null> => {
return await UserModel.findOne({ microsoftId });
},
createUser: async (userData: Partial<IUser>): Promise<IUser> => {
const user = new UserModel(userData);
return await user.save();
},
};
export const authOktaConfig = {
clientId: process.env.OKTA_CLIENT_ID as string,
clientSecret: process.env.OKTA_CLIENT_SECRET as string,
redirectUri: process.env.OKTA_REDIRECT_URI as string,
authDomain: process.env.OKTA_DOMAIN as string, // ✅ Use OKTA_DOMAIN instead of AUTH0_DOMAIN
// Find user by Okta ID in MongoDB
findUserByOktaId: async (oktaId: string): Promise<IUser | null> => {
return await UserModel.findOne({ oktaId });
},
// Create a new user if not found
createUser: async (userData: Partial<IUser>): Promise<IUser> => {
const user = new UserModel(userData);
return await user.save();
},
};
// Connect to MongoDB
mongoose
.connect(process.env.MONGO_URI as string)
.then(() => console.log("MongoDB Connected"))
.catch((err) => console.error("MongoDB connection error:", err));
app.post("/signup", async (req, res) => {
const { email, password, username } = req.body;
if (!email || !password || !username) {
return res.status(400).json({ message: "All fields are required" });
}
const result = await signupHandler(email, password, username, authemailConfig);
res.status(result.status).json(result);
});
// Login Route
app.post("/login", async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: "Email and Password are required" });
}
const result = await loginHandler(email, password, authemailConfig);
res.status(result.status).json(result);
});
app.post("/verify-otp", async (req, res) => {
const { email, otp } = req.body;
const result = await verifyOtpHandler(email, otp);
res.status(result.status).json(result);
});
app.get("/github", (req, res) => {
const authUrl = githubAuthInitiate(authConfig.clientId);
res.redirect(authUrl);
});
app.get("/github/callback", async (req, res) => {
const code = req.query.code as string;
try {
const { user } = await githubAuthCallback(code, authConfig);
res.json({ message: "Login Successful!", user });
} catch (error: any) {
res.status(500).json({ error: error.message });
}
});
app.get("/google", (req, res) => {
const authUrl = googleAuthInitiate(authGoogleConfig.clientId, authGoogleConfig.redirectUri);
res.redirect(authUrl);
});
app.get("/google/callback", async (req, res) => {
const code = req.query.code as string;
try {
const { user } = await googleAuthCallback(code, authGoogleConfig);
res.json({ message: "Login Successful!", user });
} catch (error: any) {
res.status(500).json({ error: error.message });
}
});
app.get("/microsoft", (req, res) => {
const authUrl = microsoftAuthInitiate(authMicrosftConfig.clientId, authMicrosftConfig.redirectUri);
res.redirect(authUrl);
});
app.get("/auth/microsoft/callback", async (req, res) => {
const code = req.query.code as string;
try {
const { user } = await microsoftAuthCallback(code, authMicrosftConfig);
res.json({ message: "Login Successful!", user });
} catch (error: any) {
res.status(500).json({ error: error.message });
}
});
app.get("/auth/ssologin", (req, res) => {
const authUrl = oktaAuthInitiate(authOktaConfig.clientId, authOktaConfig.redirectUri, authOktaConfig.authDomain);
res.redirect(authUrl);
});
app.get("/auth/sso/callback", async (req, res) => {
const code = req.query.code as string;
try {
const { user } = await oktaAuthCallback(code, authOktaConfig);
res.json({ message: "Login Successful!", user });
} catch (error: any) {
res.status(500).json({ error: error.message });
}
});
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
---
## License
This project is licensed under the MIT License.