Skip to content

Commit

Permalink
chore: add ability to auto verify and auto login in test env
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-bo-davis committed Apr 26, 2024
1 parent 34fc89c commit 321a2ec
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 20 deletions.
13 changes: 13 additions & 0 deletions remix/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
DATABASE_URL="postgresql://codellm:password@localhost:5432/codellm?schema=public"

AUTH0_CALLBACK_URL="http://localhost:3000/callback"
AUTH0_CLIENT_ID="your_client_id_here"
AUTH0_CLIENT_SECRET="your_client_secret_here"
AUTH0_DOMAIN="your_domain_here"
AUTH0_LOGOUT_URL="https://your_domain_here/v2/logout"

# Set to "true" to automatically verify users when they sign up
USER_AUTO_VERIFY="true"

# Set to "true" to automatically log in the mock user
USER_AUTO_LOGIN="true"
12 changes: 12 additions & 0 deletions remix/app/.server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@ export type Auth0Config = {
secrets: string;
};

export type UserConfig = {
userAutoLogin: boolean;
userAutoVerify: boolean;
};

export type Config = {
auth0: Auth0Config;
codellm: PartialConfig;
user: UserConfig;
};

let config: Config;
Expand Down Expand Up @@ -110,13 +116,19 @@ export const getAuth0Config = () =>
secrets: process.env.AUTH0_SECRETS ?? '',
}) as Auth0Config;

export const getUserConfig = () => ({
userAutoLogin: process.env.USER_AUTO_LOGIN === 'true',
userAutoVerify: process.env.USER_AUTO_VERIFY === 'true',
});

export const initConfig = () => {
config = remember(
'config',
() =>
({
auth0: getAuth0Config(),
codellm: getCodellmConfig(),
user: getUserConfig(),
}) as Config,
);
};
Expand Down
19 changes: 15 additions & 4 deletions remix/app/.server/services/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ const auth0Strategy = new Auth0Strategy(
}

const user = await userModel.getByAuth0Id(profile.id);
if (user) return profile;
if (!isError(user)) return profile;
if (!isError(user, 'userModel:notFound')) throw user;

const createRes = await userModel.create({
auth0Id: profile.id,
email: profile.emails?.[0].value || '',
firstName: profile.displayName?.split(' ')[0],
lastName: profile.displayName?.split(' ')[-1],
isVerified: getConfig('user.userAutoVerify'),
});
if (isError(createRes)) throw createRes;

Expand All @@ -66,11 +68,11 @@ export const getSession = async ({ request }: ServiceCommonParams) => {
return session;
};

export type GetLogoutURLParams = ServiceCommonParams & {
returnToPath: string;
export type LogoutParams = ServiceCommonParams & {
returnToPath?: string;
};

export const getLogoutURL = ({ request, returnToPath }: GetLogoutURLParams) => {
export const getLogoutURL = ({ request, returnToPath = '/' }: LogoutParams) => {
// Parse the request URL to get the origin and replace the path
const url = new URL(request.url);
const returnToURL = new URL(returnToPath, url.origin);
Expand All @@ -93,7 +95,16 @@ export const getLogoutOptions = async (params: ServiceCommonParams) => {
};
};

export const logout = async (params: LogoutParams) => {
const logoutUrl = getLogoutURL(params);
const logoutOptions = await getLogoutOptions(params);
if (isError(logoutOptions)) throw redirect('/');

throw redirect(logoutUrl, logoutOptions);
};

export const getAuthProfile = async ({ request }: ServiceCommonParams) => {
if (getConfig('user.userAutoLogin')) return { id: 'mock-user' };
const session = await getSession({ request });

if (!session) return null;
Expand Down
10 changes: 7 additions & 3 deletions remix/app/.server/services/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { ServiceCommonParams } from './types';
import type { UserModel } from '@remix/.server/models';
import type { RemixError } from '@remix/.server/errors';

import { redirect } from '@remix-run/node';
import { userModel } from '@remix/.server/models';
import { getAuthProfile } from '@remix/.server/services/auth';
import { getAuthProfile, logout } from '@remix/.server/services/auth';
import { isError, newError } from '@remix/.server/errors';

export const ERRORS = {
Expand All @@ -20,15 +21,18 @@ export const ERRORS = {

export const getUser = async (params: ServiceCommonParams) => {
const authUser = await getAuthProfile(params);

if (!authUser) {
return newError({
code: 'userService:noAuthUser',
message: 'No authenticated user found',
});
}

return userModel.getByAuth0Id(authUser.id);
const user = await userModel.getByAuth0Id(authUser.id);
if (isError(user, 'userModel:notFound')) return logout(params);
if (isError(user)) throw user;

return user;
};

export const validateUser = (user: UserModel | RemixError) => {
Expand Down
14 changes: 3 additions & 11 deletions remix/app/routes/logout/action.server.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import type { ActionFunctionArgs } from '@remix-run/node';
import { redirect } from '@remix-run/node';

import { getLogoutOptions, getLogoutURL } from '@remix/.server/services/auth';
import { isError } from '@remix/.server/errors';
import { logout } from '@remix/.server/services/auth';

export const action = async ({ request }: ActionFunctionArgs) => {
const logoutUrl = getLogoutURL({ request, returnToPath: '/' });
const logoutOptions = await getLogoutOptions({ request });
if (isError(logoutOptions)) {
return redirect('/');
}

throw redirect(logoutUrl, logoutOptions);
export const action = async (params: ActionFunctionArgs) => {
return logout(params);
};
4 changes: 2 additions & 2 deletions remix/prisma/seeds/users.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const users = [
{
auth0Id: 'github|7569921',
email: 'bo@interrobang.consulting',
auth0Id: 'mock-user',
email: 'bo+codellm-mock@interrobang.consulting',
firstName: 'Bo',
isVerified: true,
lastName: 'Davis',
Expand Down

0 comments on commit 321a2ec

Please sign in to comment.