🚩 add provision flow in oauth
Create a flow where if the user logs in with a registered Google account, they are immediately authenticated, but if no account is found, create a new one.
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
export interface LoginIfExistAndCreateIfNot {
|
||||
email: string;
|
||||
username?: string;
|
||||
export interface GoogleCallbackUserData {
|
||||
sub: string;
|
||||
name: string;
|
||||
provider: "Google" | "GitHub";
|
||||
given_name: string;
|
||||
family_name: string;
|
||||
picture: string;
|
||||
email: string;
|
||||
email_verified: boolean;
|
||||
}
|
||||
|
||||
@ -2,12 +2,15 @@ import { Context } from "elysia";
|
||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||
import { googleCallbackService } from "../services/http/googleCallback.service";
|
||||
import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation";
|
||||
|
||||
export const googleCallbackController = async (
|
||||
ctx: Context & { query: { code: string; state: string } }
|
||||
) => {
|
||||
try {
|
||||
const userData = await googleCallbackService(ctx.query);
|
||||
const userHeaderInfo = getUserHeaderInformation(ctx);
|
||||
|
||||
const userData = await googleCallbackService(ctx.query, userHeaderInfo);
|
||||
return returnWriteResponse(
|
||||
ctx.set,
|
||||
200,
|
||||
|
||||
@ -2,11 +2,17 @@ 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;
|
||||
}) => {
|
||||
export const googleCallbackService = async (
|
||||
query: {
|
||||
state: string;
|
||||
code: string;
|
||||
},
|
||||
userHeaderInfo: UserHeaderInformation
|
||||
) => {
|
||||
try {
|
||||
// get code and state for validation from params and search for state in redis cache
|
||||
const state = query.state;
|
||||
@ -36,7 +42,19 @@ export const googleCallbackService = async (query: {
|
||||
}
|
||||
);
|
||||
|
||||
return await response.json();
|
||||
const userData = (await response.json()) as GoogleCallbackUserData;
|
||||
|
||||
return await OAuthUserProvisionService(
|
||||
{
|
||||
providerName: "google",
|
||||
openId: userData.sub,
|
||||
email: userData.email,
|
||||
name: userData.name,
|
||||
avatar: userData.picture,
|
||||
},
|
||||
userData,
|
||||
userHeaderInfo
|
||||
);
|
||||
} catch (error) {
|
||||
ErrorForwarder(error, 500, "Authentication service error");
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
import { UserHeaderInformation } from "../../../../helpers/http/userHeader/getUserHeaderInformation/types";
|
||||
import { findUserService } from "../../../user/services/internal/findUser.service";
|
||||
|
||||
export const OAuthUserProvisionService = async (
|
||||
payload: {
|
||||
providerName: string;
|
||||
openId: string;
|
||||
email: string;
|
||||
username?: string;
|
||||
name: string;
|
||||
avatar?: string;
|
||||
bio?: string;
|
||||
},
|
||||
providerRawCallback: unknown,
|
||||
userHeaderInfo: UserHeaderInformation
|
||||
) => {
|
||||
/**
|
||||
* Create auth session if user already exist,
|
||||
* create user account and give them auth session if not
|
||||
*
|
||||
* This is just example!!
|
||||
*/
|
||||
const providerId = `${payload.providerName}_${payload.openId}`;
|
||||
const findUserResult = await findUserService({
|
||||
identifier: providerId,
|
||||
queryTarget: "providerId",
|
||||
options: { verbosity: "exists" },
|
||||
});
|
||||
|
||||
if (findUserResult) {
|
||||
return "Already Created";
|
||||
} else {
|
||||
return "Not Found";
|
||||
}
|
||||
};
|
||||
@ -1,6 +0,0 @@
|
||||
export const loginIfExistAndCreateIfNotService = () => {
|
||||
/**
|
||||
* Create auth session if user already exist,
|
||||
* create user account and give them auth session if not
|
||||
*/
|
||||
};
|
||||
Reference in New Issue
Block a user