Merge branch 'main' into test/backend-test-case

This commit is contained in:
Mir Arif Hasan
2023-07-14 14:34:39 +06:00
committed by GitHub
86 changed files with 793 additions and 192 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "hoppscotch-backend",
"version": "2023.4.5",
"version": "2023.4.7",
"description": "",
"author": "",
"private": true,

View File

@@ -236,11 +236,12 @@ export class AdminService {
const user = await this.userService.findUserByEmail(userEmail);
if (O.isNone(user)) return E.left(USER_NOT_FOUND);
const isUserAlreadyMember = await this.teamService.getTeamMemberTE(
const teamMember = await this.teamService.getTeamMemberTE(
teamID,
user.value.uid,
)();
if (E.isLeft(isUserAlreadyMember)) {
if (E.isLeft(teamMember)) {
const addedUser = await this.teamService.addMemberToTeamWithEmail(
teamID,
userEmail,
@@ -248,6 +249,18 @@ export class AdminService {
);
if (E.isLeft(addedUser)) return E.left(addedUser.left);
const userInvitation =
await this.teamInvitationService.getTeamInviteByEmailAndTeamID(
userEmail,
teamID,
);
if (E.isRight(userInvitation)) {
await this.teamInvitationService.revokeInvitation(
userInvitation.right.id,
)();
}
return E.right(addedUser.right);
}

View File

@@ -17,7 +17,7 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy) {
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
callbackURL: process.env.MICROSOFT_CALLBACK_URL,
scope: [process.env.MICROSOFT_SCOPE],
passReqToCallback: true,
tenant: process.env.MICROSOFT_TENANT,
store: true,
});
}

View File

@@ -23,7 +23,7 @@ export const AUTH_FAIL = 'auth/fail';
export const JSON_INVALID = 'json_invalid';
/**
* Tried to delete an user data document from fb firestore but failed.
* Tried to delete a user data document from fb firestore but failed.
* (FirebaseService)
*/
export const USER_FB_DOCUMENT_DELETION_FAILED =
@@ -231,7 +231,7 @@ export const TEAM_COLL_INVALID_JSON = 'team_coll/invalid_json';
export const TEAM_NOT_OWNER = 'team_coll/team_not_owner' as const;
/**
* Tried to perform action on a request that doesn't accept their member role level
* Tried to perform an action on a request that doesn't accept their member role level
* (GqlRequestTeamMemberGuard)
*/
export const TEAM_REQ_NOT_REQUIRED_ROLE = 'team_req/not_required_role';
@@ -262,7 +262,7 @@ export const TEAM_REQ_REORDERING_FAILED = 'team_req/reordering_failed' as const;
export const SENDER_EMAIL_INVALID = 'mailer/sender_email_invalid' as const;
/**
* Tried to perform action on a request when the user is not even member of the team
* Tried to perform an action on a request when the user is not even a member of the team
* (GqlRequestTeamMemberGuard, GqlCollectionTeamMemberGuard)
*/
export const TEAM_REQ_NOT_MEMBER = 'team_req/not_member';
@@ -307,7 +307,7 @@ export const SHORTCODE_INVALID_JSON = 'shortcode/invalid_json' as const;
export const SHORTCODE_ALREADY_EXISTS = 'shortcode/already_exists' as const;
/**
* Invalid or non-existent TEAM ENVIRONMMENT ID
* Invalid or non-existent TEAM ENVIRONMENT ID
* (TeamEnvironmentsService)
*/
export const TEAM_ENVIRONMENT_NOT_FOUND = 'team_environment/not_found' as const;
@@ -340,7 +340,7 @@ export const USER_SETTINGS_NULL_SETTINGS =
'user_settings/null_settings' as const;
/*
* Global environment doesnt exists for the user
* Global environment doesn't exist for the user
* (UserEnvironmentsService)
*/
export const USER_ENVIRONMENT_GLOBAL_ENV_DOES_NOT_EXISTS =

View File

@@ -3,6 +3,7 @@ import * as T from 'fp-ts/Task';
import * as O from 'fp-ts/Option';
import * as TO from 'fp-ts/TaskOption';
import * as TE from 'fp-ts/TaskEither';
import * as E from 'fp-ts/Either';
import { pipe, flow, constVoid } from 'fp-ts/function';
import { PrismaService } from 'src/prisma/prisma.service';
import { Team, TeamMemberRole } from 'src/team/team.model';
@@ -10,6 +11,7 @@ import { Email } from 'src/types/Email';
import { User } from 'src/user/user.model';
import { TeamService } from 'src/team/team.service';
import {
INVALID_EMAIL,
TEAM_INVITE_ALREADY_MEMBER,
TEAM_INVITE_EMAIL_DO_NOT_MATCH,
TEAM_INVITE_MEMBER_HAS_INVITE,
@@ -19,6 +21,7 @@ import { TeamInvitation } from './team-invitation.model';
import { MailerService } from 'src/mailer/mailer.service';
import { UserService } from 'src/user/user.service';
import { PubSubService } from 'src/pubsub/pubsub.service';
import { validateEmail } from '../utils';
@Injectable()
export class TeamInvitationService {
@@ -63,6 +66,32 @@ export class TeamInvitationService {
);
}
/**
* Get the team invite for an invitee with email and teamID.
* @param inviteeEmail invitee email
* @param teamID team id
* @returns an Either of team invitation for the invitee or error
*/
async getTeamInviteByEmailAndTeamID(inviteeEmail: string, teamID: string) {
const isEmailValid = validateEmail(inviteeEmail);
if (!isEmailValid) return E.left(INVALID_EMAIL);
try {
const teamInvite = await this.prisma.teamInvitation.findUniqueOrThrow({
where: {
teamID_inviteeEmail: {
inviteeEmail: inviteeEmail,
teamID: teamID,
},
},
});
return E.right(teamInvite);
} catch (e) {
return E.left(TEAM_INVITE_NO_INVITE_FOUND);
}
}
createInvitation(
creator: User,
team: Team,

View File

@@ -32,7 +32,7 @@ export class TeamInviteViewerGuard implements CanActivate {
// Get user
TE.bindW('user', ({ gqlCtx }) =>
pipe(
O.fromNullable(gqlCtx.getContext<{ user?: User }>().user),
O.fromNullable(gqlCtx.getContext().req.user),
TE.fromOption(() => BUG_AUTH_NO_USER_CTX),
),
),

View File

@@ -33,7 +33,7 @@ export class TeamInviteeGuard implements CanActivate {
// Get user
TE.bindW('user', ({ gqlCtx }) =>
pipe(
O.fromNullable(gqlCtx.getContext<{ user?: User }>().user),
O.fromNullable(gqlCtx.getContext().req.user),
TE.fromOption(() => BUG_AUTH_NO_USER_CTX),
),
),

View File

@@ -2,7 +2,7 @@ import { HttpStatus } from '@nestjs/common';
/**
** Custom interface to handle errors specific to Auth module
** Since its REST we need to return HTTP status code along with error message
** Since its REST we need to return the HTTP status code along with the error message
*/
export type AuthError = {
message: string;