Files
AnimeTV-Backend/src/modules/auth/services/http/googleCallback.service.ts

60 lines
2.3 KiB
TypeScript

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";
import { UserHeaderInformation } from "../../../../helpers/http/userHeader/getUserHeaderInformation/types";
import { OAuthUserProvisionService } from "../internal/OAuthUserProvision.service";
import { GoogleCallbackUserData } from "../../auth.types";
export const googleCallbackService = async (
query: {
state: string;
code: string;
callbackURI?: string;
},
userHeaderInfo: UserHeaderInformation,
) => {
try {
// get code and state for validation from params and search for state in redis cache
const state = query.state;
const codeVerifier = await redis.get(`${process.env.APP_NAME}:pkce:${state}`);
// return error if the state for validation is not found in redis, and delete if found
if (!codeVerifier) throw new AppError(408, "Request timeout");
await redis.del(`${process.env.APP_NAME}:pkce:${state}`);
// create access token with the result of validating the authorization code that compares access code with validator state
const google = googleProvider(query.callbackURI);
const tokens = await google.validateAuthorizationCode(query.code, codeVerifier);
// get user data from Google using the access token that has been created.
const accessToken = tokens.accessToken();
const response = await fetch("https://openidconnect.googleapis.com/v1/userinfo", {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
// parse the user data response
const userData = (await response.json()) as GoogleCallbackUserData;
// Provision or authenticate the user in the system
return await OAuthUserProvisionService(
{
fullname: userData.name,
username: `gle_${userData.sub}`,
email: userData.email,
avatar: userData.picture,
oauthProvider: {
providerName: "google",
sub: userData.sub,
token: accessToken,
},
},
userHeaderInfo,
);
} catch (error) {
ErrorForwarder(error, 500, "Authentication service error");
}
};