Skip to content

Commit

Permalink
Merge pull request #2065 from ever-co/refact/api
Browse files Browse the repository at this point in the history
[Refact] move API routes from `page/api` to `app/api` folder
  • Loading branch information
evereq authored Jan 7, 2024
2 parents 0d89acf + d083f6a commit 14f4446
Show file tree
Hide file tree
Showing 121 changed files with 1,940 additions and 1,477 deletions.
5 changes: 4 additions & 1 deletion apps/web/app/[locale]/settings/personal/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import { fullWidthState } from '@app/stores/fullWidth';
const Personal = () => {
const t = useTranslations();
const [user] = useRecoilState(userState);
const breadcrumb = [...JSON.parse(t('pages.settings.BREADCRUMB'))];
const breadcrumb = [
{ title: JSON.parse(t('pages.home.BREADCRUMB')), href: '/' },
{ title: JSON.parse(t('pages.settings.BREADCRUMB')), href: '/settings/personnal' }
];
const fullWidth = useRecoilValue(fullWidthState);

return (
Expand Down
5 changes: 4 additions & 1 deletion apps/web/app/[locale]/settings/team/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ const Team = () => {
const [user] = useRecoilState(userState);
const { isTeamMember, activeTeam } = useOrganizationTeams();
const { isTeamManager } = useIsMemberManager(user);
const breadcrumb = [...JSON.parse(t('pages.settings.BREADCRUMB'))];
const breadcrumb = [
{ title: JSON.parse(t('pages.home.BREADCRUMB')), href: '/' },
{ title: JSON.parse(t('pages.settings.BREADCRUMB')), href: '/settings/team' }
];
const fullWidth = useRecoilValue(fullWidthState);
return (
<>
Expand Down
192 changes: 192 additions & 0 deletions apps/web/app/api/auth/_signin-workspace/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { authFormValidate } from '@app/helpers/validations';
import {
acceptInviteRequest,
getAllOrganizationTeamRequest,
getUserOrganizationsRequest,
signInWorkspaceRequest,
verifyInviteCodeRequest
} from '@app/services/server/requests';
import { generateToken, setAuthCookies, setNoTeamPopupShowCookie } from '@app/helpers';
import { ILoginResponse } from '@app/interfaces';
import { NextResponse } from 'next/server';

export async function POST(req: Request) {
try {
const res = new NextResponse();

const body = (await req.json()) as unknown as {
email: string;
token: string;
teamId: string;
code: string;
};
let loginResponse: ILoginResponse | null = null;

const { errors, valid: formValid } = authFormValidate(['email'], body as any);

if (!formValid) {
return NextResponse.json({ errors }, { status: 400 });
}

// Accept Invite Flow Start
/**
* Verify first if match with invite code
*/
const inviteReq = await verifyInviteCodeRequest({
email: body.email,
code: body.code
}).catch((err) => console.log(err));

// General a random password with 8 chars
if (inviteReq && inviteReq.data.fullName) {
const password = generateToken(8);

const names = inviteReq.data.fullName.split(' ');
const acceptInviteRes = await acceptInviteRequest({
code: body.code,
email: body.email,
password: password,
user: {
firstName: names[0],
lastName: names[1] || '',
email: body.email
}
}).catch(() => void 0);

if (
!acceptInviteRes ||
!acceptInviteRes.response.ok ||
acceptInviteRes.response.status === 401 ||
acceptInviteRes.response.status === 400 ||
(acceptInviteRes?.data as any).response.statusCode
) {
return NextResponse.json(
{
errors: {
email: 'Authentication code or email address invalid'
}
},
{ status: 401 }
);
}
loginResponse = acceptInviteRes.data;

if (!loginResponse) {
return NextResponse.json(
{
errors: {
email: 'Authentication code or email address invalid'
}
},
{ status: 401 }
);
}
}
if (loginResponse) {
console.log('loginResponse>>>', loginResponse);

/**
* Get the first team from first organization
*/
const tenantId = loginResponse.user?.tenantId || '';
const access_token = loginResponse.token;
const userId = loginResponse.user?.id;

const { data: organizations } = await getUserOrganizationsRequest({ tenantId, userId }, access_token);
const organization = organizations?.items[0];

console.log({ t: 5, organization });

if (!organization) {
return NextResponse.json(
{
errors: {
email: 'Your account is not yet ready to be used on the Ever Teams Platform'
}
},
{ status: 401 }
);
}
const { data: teams } = await getAllOrganizationTeamRequest(
{ tenantId, organizationId: organization.organizationId },
access_token
);

const team = teams.items[0];
if (!team) {
setNoTeamPopupShowCookie(true);
}
setAuthCookies(
{
access_token: loginResponse.token,
refresh_token: {
token: loginResponse.refresh_token
},
teamId: team?.id,
tenantId,
organizationId: organization?.organizationId,
languageId: 'en', // TODO: not sure what should be here
noTeamPopup: true,
userId
},
req,
res
);
return NextResponse.json({ team, loginResponse });
}
// Accept Invite Flow End

const { data } = await signInWorkspaceRequest(body.email, body.token);

/**
* Get the first team from first organization
*/
const tenantId = data.user?.tenantId || '';
const access_token = data.token;
const userId = data.user?.id;

const { data: organizations } = await getUserOrganizationsRequest({ tenantId, userId }, access_token);

const organization = organizations?.items[0];

if (!organization) {
return NextResponse.json(
{
errors: {
email: 'Your account is not yet ready to be used on the Ever Teams Platform'
}
},
{ status: 400 }
);
}

setAuthCookies(
{
access_token: data.token,
refresh_token: {
token: data.refresh_token
},
teamId: body.teamId,
tenantId,
organizationId: organization?.organizationId,
languageId: 'en', // TODO: not sure what should be here
noTeamPopup: true,
userId
},
req,
res
);

return NextResponse.json({ loginResponse: data });
} catch (err) {
console.log({ err });
return NextResponse.json(
{
errors: {
err
}
},
{ status: 400 }
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import {
verifyAuthCodeRequest,
verifyInviteCodeRequest
} from '@app/services/server/requests';
import { NextApiRequest, NextApiResponse } from 'next';
import { NextResponse } from 'next/server';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const body = req.body as ILoginDataAPI;
export async function POST(req: Request) {
const res = new NextResponse();
const body = (await req.json()) as unknown as ILoginDataAPI;
let loginResponse: ILoginResponse | null = null;

const { errors, valid: formValid } = authFormValidate(['email', 'code'], body as any);

if (!formValid) {
return res.status(400).json({ errors });
return NextResponse.json({ errors });
}

/**
Expand All @@ -40,7 +41,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
(authReq.data as any).status === 400 ||
(authReq.data as any).status === 401
) {
return res.status(200).json({
return NextResponse.json({
errors: {
email: 'Authentication code or email address invalid'
}
Expand All @@ -50,7 +51,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
loginResponse = authReq.data;
} catch (error) {
// return notFound(res);
return res.status(200).json({
return NextResponse.json({
errors: {
email: 'Authentication code or email address invalid'
}
Expand Down Expand Up @@ -83,7 +84,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
acceptInviteRes.response.status === 400 ||
(acceptInviteRes.data as any).response?.statusCode
) {
return res.status(400).json({
return NextResponse.json({
errors: {
email: 'Authentication code or email address invalid'
}
Expand All @@ -94,7 +95,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}

if (!loginResponse) {
return res.status(400).json({
return NextResponse.json({
errors: {
email: 'Authentication code or email address invalid'
}
Expand All @@ -113,7 +114,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const organization = organizations?.items[0];

if (!organization) {
return res.status(400).json({
return NextResponse.json({
errors: {
email: 'Your account is not yet ready to be used on the Ever Teams Platform'
}
Expand All @@ -128,7 +129,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const team = teams.items[0];

if (!team) {
setNoTeamPopupShowCookie(true);
setNoTeamPopupShowCookie(true);
}

setAuthCookies(
Expand All @@ -148,5 +149,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
res
);

res.status(200).json({ team, loginResponse });
return NextResponse.json({ team, loginResponse });
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { MEET_DOMAIN, MEET_JWT_APP_ID, MEET_JWT_APP_SECRET } from '@app/constant
// // getMeetJwtSessionCookie,
// setMeetJwtSessionCookie,
// } from '@app/helpers';
import { authenticatedGuard } from '@app/services/server/guards/authenticated-guard';
import { authenticatedGuard } from '@app/services/server/guards/authenticated-guard-app';
import jwt from 'jsonwebtoken';

import { NextApiRequest, NextApiResponse } from 'next';
import { NextResponse } from 'next/server';

const algo: jwt.SignOptions = { algorithm: 'HS256' };
type Params = {
Expand Down Expand Up @@ -40,12 +40,13 @@ function generateToken(params: Params): string {
return jwt.sign(payload, params.appkey, algo);
}

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
export async function GET(req: Request) {
const res = new NextResponse();
const { $res, user } = await authenticatedGuard(req, res);
if (!user) return $res();
if (!user) return $res('Unauthorized');

if (!MEET_JWT_APP_SECRET || !MEET_JWT_APP_ID || !MEET_DOMAIN) {
return $res.status(400).json('Invalid configuration !');
return $res('Invalid configuration !');
}

// Check if existing token from cookie is valid
Expand Down Expand Up @@ -73,5 +74,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
// We don't use this cookie for now
// setMeetJwtSessionCookie(new_token, { req, res });

res.status(200).json({ token: new_token });
return NextResponse.json({ token: new_token });
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { setAccessTokenCookie } from '@app/helpers/cookies';
import { hasErrors } from '@app/helpers/validations';
import { currentAuthenticatedUserRequest, refreshTokenRequest } from '@app/services/server/requests/auth';
import { NextApiRequest, NextApiResponse } from 'next';
import { NextResponse } from 'next/server';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).send({});
}
export async function POST(req: Request) {
const res = new NextResponse();

const body = req.body as { refresh_token: string } | null;
const body = (await req.json()) as { refresh_token: string } | null;
const refresh_token = body?.refresh_token;

if (!refresh_token || refresh_token.trim().length < 2) {
return res.status(401).json(
return NextResponse.json(
hasErrors({
refresh_token: 'The refresh token must be provided on the request body'
})
Expand All @@ -21,7 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)

const { data } = await refreshTokenRequest(refresh_token);
if (!data) {
return res.status(401);
return NextResponse.error();
}

const { data: user } = await currentAuthenticatedUserRequest({
Expand All @@ -30,5 +28,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)

setAccessTokenCookie(data.token, { res, req });

res.status(200).json({ user, token: data.token });
return NextResponse.json({ user, token: data.token });
}
Loading

0 comments on commit 14f4446

Please sign in to comment.