Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions backend/typescript/graphql/resolvers/authResolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ const authResolvers = {
);
return isAuthorized;
},
isAuthorizedAdmin: async (
_parent: undefined,
{ accessToken }: { accessToken: string },
): Promise<boolean> => {
const isAuthorized = await authService.isAuthorizedAdmin(accessToken);
return isAuthorized;
},
},
Mutation: {
login: async (
Expand Down
1 change: 1 addition & 0 deletions backend/typescript/graphql/types/authType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const authType = gql`
extend type Query {
login(email: String!, password: String!): loginOK!
isAuthorizedByRole(accessToken: String!, roles: [Role!]!): Boolean!
isAuthorizedAdmin(accessToken: String!): Boolean!
}

extend type Mutation {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { DataType } from "sequelize-typescript";
import { Migration } from "../umzug";

const TABLE_NAME = "admins";

export const up: Migration = async ({ context: sequelize }) => {
await sequelize.getQueryInterface().addColumn(TABLE_NAME, "createdAt", {
type: DataType.DATE,
allowNull: false,
defaultValue: sequelize.literal("NOW()"),
});
await sequelize.getQueryInterface().addColumn(TABLE_NAME, "updatedAt", {
type: DataType.DATE,
allowNull: false,
defaultValue: sequelize.literal("NOW()"),
});
};

export const down: Migration = async ({ context: sequelize }) => {
await sequelize.getQueryInterface().removeColumn(TABLE_NAME, "createdAt");
await sequelize.getQueryInterface().removeColumn(TABLE_NAME, "updatedAt");
};
15 changes: 15 additions & 0 deletions backend/typescript/services/implementations/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AuthDTO, Role, Token } from "../../types";
import { getErrorMessage } from "../../utilities/errorUtils";
import FirebaseRestClient from "../../utilities/firebaseRestClient";
import logger from "../../utilities/logger";
import Admin from "../../models/admin.model";

const Logger = logger(__filename);

Expand Down Expand Up @@ -272,6 +273,20 @@ class AuthService implements IAuthService {
throw error;
}
}

async isAuthorizedAdmin(accessToken: string): Promise<boolean> {
try {
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken =
await firebaseAdmin.auth().verifyIdToken(accessToken, true);
const userId = await this.userService.getUserIdByAuthId(
decodedIdToken.uid,
);
const adminEntry = await Admin.findOne({ where: { userId } });
return !!adminEntry;
} catch (error) {
return false;
}
}
}

export default AuthService;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApplicantRecordDTO } from "../../types";
import { ApplicantRecordDTO, ApplicationStatus } from "../../types";

interface IApplicantRecordService {
updateApplicantStatus(
Expand All @@ -8,7 +8,7 @@ interface IApplicantRecordService {
bulkUpdateApplicantStatus(
applicantRecordIds: string[],
status: ApplicationStatus,
): Promise<ApplicantRecordDto[]>;
): Promise<ApplicantRecordDTO[]>;
setApplicantRecordFlag(
applicantRecordId: string,
flagValue: boolean,
Expand Down
7 changes: 7 additions & 0 deletions backend/typescript/services/interfaces/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ interface IAuthService {
* @returns true if email sent successfully
*/
sendSignInLink(email: string): Promise<boolean>;

/**
* Determine if the user associated with the provided access token is an admin
* @param accessToken user's access token
* @returns true if Admin entry exists with userId associated with accessToken, false otherwise
*/
isAuthorizedAdmin(accessToken: string): Promise<boolean>;
}

export default IAuthService;
Loading