✨ add new oauth provider
add google idconnect as new auth provider
This commit is contained in:
@ -205,6 +205,10 @@ model User {
|
|||||||
bioProfile String? @db.Text
|
bioProfile String? @db.Text
|
||||||
avatar String? @db.Text
|
avatar String? @db.Text
|
||||||
commentBackground String? @db.Text
|
commentBackground String? @db.Text
|
||||||
|
provider String? @db.VarChar(255)
|
||||||
|
providerId String? @unique @db.VarChar(255)
|
||||||
|
providerToken String? @db.Text
|
||||||
|
providerPayload Json? @db.Json
|
||||||
preference UserPreference? @relation(fields: [preferenceId], references: [id])
|
preference UserPreference? @relation(fields: [preferenceId], references: [id])
|
||||||
preferenceId String? @unique
|
preferenceId String? @unique
|
||||||
verifiedAt DateTime?
|
verifiedAt DateTime?
|
||||||
|
|||||||
20
src/modules/auth/controllers/googleCallback.controller.ts
Normal file
20
src/modules/auth/controllers/googleCallback.controller.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Context } from "elysia";
|
||||||
|
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
||||||
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
|
import { googleCallbackService } from "../services/googleCallback.service";
|
||||||
|
|
||||||
|
export const googleCallbackController = async (
|
||||||
|
ctx: Context & { query: { code: string; state: string } }
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const userData = await googleCallbackService(ctx.query);
|
||||||
|
return returnWriteResponse(
|
||||||
|
ctx.set,
|
||||||
|
200,
|
||||||
|
"Authenticated successfully!",
|
||||||
|
userData
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return mainErrorHandler(ctx.set, error);
|
||||||
|
}
|
||||||
|
};
|
||||||
18
src/modules/auth/controllers/googleRequest.controller.ts
Normal file
18
src/modules/auth/controllers/googleRequest.controller.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Context } from "elysia";
|
||||||
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
|
import { googleRequestService } from "../services/googleRequest.service";
|
||||||
|
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
||||||
|
|
||||||
|
export const googleRequestController = async (ctx: Context) => {
|
||||||
|
try {
|
||||||
|
const loginUrl = await googleRequestService();
|
||||||
|
return returnReadResponse(
|
||||||
|
ctx.set,
|
||||||
|
200,
|
||||||
|
"Google login url created!",
|
||||||
|
loginUrl
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return mainErrorHandler(ctx.set, error);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,7 +1,11 @@
|
|||||||
import Elysia from "elysia";
|
import Elysia from "elysia";
|
||||||
import { githubRequestController } from "./controllers/githubRequest.controller";
|
import { githubRequestController } from "./controllers/githubRequest.controller";
|
||||||
import { githubCallbackController } from "./controllers/githubCallback.controller";
|
import { githubCallbackController } from "./controllers/githubCallback.controller";
|
||||||
|
import { googleRequestController } from "./controllers/googleRequest.controller";
|
||||||
|
import { googleCallbackController } from "./controllers/googleCallback.controller";
|
||||||
|
|
||||||
export const authModule = new Elysia({ prefix: "/auth" })
|
export const authModule = new Elysia({ prefix: "/auth" })
|
||||||
.get("/github", githubRequestController)
|
.get("/github", githubRequestController)
|
||||||
.get("/github/callback", githubCallbackController);
|
.get("/github/callback", githubCallbackController)
|
||||||
|
.get("/google", googleRequestController)
|
||||||
|
.get("/google/callback", googleCallbackController);
|
||||||
|
|||||||
10
src/modules/auth/providers/google.provider.ts
Normal file
10
src/modules/auth/providers/google.provider.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Google } from "arctic";
|
||||||
|
|
||||||
|
export const googleProvider = () => {
|
||||||
|
const redirectURI = `${process.env.APP_PROTOCOL}://${process.env.APP_DOMAIN}${process.env.GOOGLE_CLIENT_CALLBACK}`;
|
||||||
|
return new Google(
|
||||||
|
process.env.GOOGLE_CLIENT_ID!,
|
||||||
|
process.env.GOOGLE_CLIENT_SECRET!,
|
||||||
|
redirectURI
|
||||||
|
);
|
||||||
|
};
|
||||||
36
src/modules/auth/services/googleCallback.service.ts
Normal file
36
src/modules/auth/services/googleCallback.service.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { AppError } from "../../../helpers/error/instances/app";
|
||||||
|
import { googleProvider } from "../providers/google.provider";
|
||||||
|
import { redis } from "../../../utils/databases/redis/connection";
|
||||||
|
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
||||||
|
|
||||||
|
export const googleCallbackService = async (query: {
|
||||||
|
state: string;
|
||||||
|
code: string;
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
const state = query.state;
|
||||||
|
const codeVerifier = await redis.get(
|
||||||
|
`${process.env.APP_NAME}:pkce:${state}`
|
||||||
|
);
|
||||||
|
if (!codeVerifier) throw new AppError(408, "Request timeout");
|
||||||
|
await redis.del(`${process.env.APP_NAME}:pkce:${state}`);
|
||||||
|
|
||||||
|
const google = googleProvider();
|
||||||
|
const tokens = await google.validateAuthorizationCode(
|
||||||
|
query.code,
|
||||||
|
codeVerifier
|
||||||
|
);
|
||||||
|
const accessToken = tokens.accessToken();
|
||||||
|
const response = await fetch(
|
||||||
|
"https://openidconnect.googleapis.com/v1/userinfo",
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${accessToken}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
ErrorForwarder(error, 500, "Authentication service error");
|
||||||
|
}
|
||||||
|
};
|
||||||
28
src/modules/auth/services/googleRequest.service.ts
Normal file
28
src/modules/auth/services/googleRequest.service.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import * as arctic from "arctic";
|
||||||
|
import { AppError } from "../../../helpers/error/instances/app";
|
||||||
|
import { googleProvider } from "../providers/google.provider";
|
||||||
|
import { redis } from "../../../utils/databases/redis/connection";
|
||||||
|
|
||||||
|
export const googleRequestService = async () => {
|
||||||
|
try {
|
||||||
|
const google = googleProvider();
|
||||||
|
const state = arctic.generateState();
|
||||||
|
const codeVerifier = arctic.generateCodeVerifier();
|
||||||
|
const scopes = ["openid", "profile", "email"];
|
||||||
|
const url = google.createAuthorizationURL(state, codeVerifier, scopes);
|
||||||
|
|
||||||
|
await redis.setex(
|
||||||
|
`${process.env.APP_NAME}:pkce:${state}`,
|
||||||
|
300,
|
||||||
|
codeVerifier
|
||||||
|
);
|
||||||
|
|
||||||
|
return url;
|
||||||
|
} catch (error) {
|
||||||
|
throw new AppError(
|
||||||
|
500,
|
||||||
|
"Google Auth provider is experiencing issues.",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user