Skip to content
This repository has been archived by the owner on Nov 19, 2021. It is now read-only.

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
Allypost committed Apr 27, 2021
1 parent e4440bb commit 7bac835
Show file tree
Hide file tree
Showing 69 changed files with 3,440 additions and 546 deletions.
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ SENTRY_DSN=https://[email protected]/544
JWT_SECRET=

DB_URL=postgresql://postgres:postgres@meetup-db/meetup

MAILSERVER_ADDRESS=
MAILSERVER_PORT=
MAILSERVER_USERNAME=
MAILSERVER_PASSWORD=

2 changes: 1 addition & 1 deletion api/helpers/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ export class HttpStatus {


export const internalRequest = async (method, url, ...rest) => {
const baseUrl = `http://localhost:${ "development" === process.env.NODE_ENV ? "3000" : process.env.PORT }/api`;
const baseUrl = `http://localhost:${ process.env.PORT }/api`;
const fetchUrl = `${ baseUrl }${ url }`;

try {
Expand Down
4 changes: 2 additions & 2 deletions api/helpers/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "./token";
import {
hasPermission,
RoleNames,
Role,
} from "./permissions";
import {
error,
Expand Down Expand Up @@ -49,7 +49,7 @@ export const injectAuthData =
export const requireAuth =
({
fullUserData = false,
role = RoleNames.BASE,
role = Role.base,
} = {}) =>
async (req, res, next) => {
await injectAuthData({ fullUserData })(req);
Expand Down
37 changes: 21 additions & 16 deletions api/helpers/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,41 @@ import map from "lodash/fp/map";

const mapWithIndex = map.convert({ cap: false });

export enum RoleNames {
BASE = "nobody",
STUDENT = "student",
ACCOUNT_MANAGER = "account_manager",
MODERATOR = "moderator",
ADMIN = "admin",
// This is just a noop function to force the TS compiler to typecheck the enum
const ensureEnumKeysSameAsValues = <T>(_kv: { [K in keyof T]: K }) => null;

export enum Role {
base = "base",
company = "company",
student = "student",
moderator = "moderator",
admin = "admin",
}

const roleNameToPriority: Record<RoleNames, number> =
ensureEnumKeysSameAsValues(Role);

const roleNameToPriority: Record<Role, number> =
flow(
values,
mapWithIndex((value: RoleNames, i: number) => [ value, i ]),
mapWithIndex((value: Role, i: number) => [ value, i ]),
fromPairs,
)(RoleNames)
)(Role)
;

export const hasPermission =
(
minimumRoleName: RoleNames,
currentRoleName: RoleNames,
minimumRoleName: Role,
currentRoleName: Role,
): boolean =>
roleNameToPriority[minimumRoleName] <= roleNameToPriority[currentRoleName]
;

const isAtLeast =
(role: RoleNames) =>
(roleName: RoleNames) =>
(role: Role) =>
(roleName: Role) =>
hasPermission(role, roleName)
;

export const isAdmin = isAtLeast(RoleNames.ADMIN);
export const isModerator = isAtLeast(RoleNames.MODERATOR);
export const isStudent = isAtLeast(RoleNames.BASE);
export const isAdmin = isAtLeast(Role.admin);
export const isModerator = isAtLeast(Role.moderator);
export const isStudent = isAtLeast(Role.student);
79 changes: 16 additions & 63 deletions api/helpers/token.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
import {
verify,
} from "jsonwebtoken";
import {
keysFromSnakeToCamelCase,
} from "../../helpers/object";
import {
basicUserQuery,
currentUserQuery,
} from "../graphql/queries";
import CompanyService from "../services/company-service";
import {
getSetting,
} from "./settings";
import {
graphQlQuery,
} from "./axios";
import {
internalRequest,
} from "./http";
import UserService from "../services/user-service";

export const extractAuthorizationToken = (req) => {
const header = req.get("Authorization");
Expand Down Expand Up @@ -54,14 +38,14 @@ export const verifiedJwt =
},
) =>
new Promise(
(resolve, reject) =>
(resolve) =>
verify(
token,
secret,
options,
(err, data) => {
if (err) {
reject(err);
resolve(null);
} else {
resolve(data);
}
Expand All @@ -70,7 +54,9 @@ export const verifiedJwt =
)
;

export const fetchAuthenticatedUser = async (reqOrToken, fullUser = false) => {
export const getJwtSecret = () => `jobfair-meetup-secret-${ process.env.JWT_SECRET || "very secret :)" }`;

export const fetchAuthenticatedUser = async (reqOrToken, _fullUser = false) => {
const auth =
"string" === typeof reqOrToken
? reqOrToken
Expand All @@ -81,51 +67,18 @@ export const fetchAuthenticatedUser = async (reqOrToken, fullUser = false) => {
return null;
}

try {
// Should be a string of format `jwt $AUTH_TOKEN`
const token = auth.substr("jwt ".length);
const secret = await getSetting("JWT Secret", process.env.JWT_SECRET);

const data = await verifiedJwt({
token,
secret,
});

if (!("role" in data)) {
return null;
}

if (false === fullUser) {
return data;
}
} catch (e) {
console.log("Failed local JWT verification:", e.message);
}

try {
const { current_user: rawUser } = await graphQlQuery(
fullUser ? currentUserQuery() : basicUserQuery(),
auth,
);

const user = keysFromSnakeToCamelCase({
uid: rawUser.resume && rawUser.resume.uid,
...rawUser,
});

delete user.resume;

const { companies = [] } = user;
// Should be a string of format `jwt $AUTH_TOKEN`
const token = auth.substr("jwt ".length);
const secret = getJwtSecret();

if (companies) {
const { data: rawParticipants = [] } = await internalRequest("get", "/companies/participants");
const participantIds = new Set(rawParticipants.map(({ id }) => id));
const jwtData = await verifiedJwt({
token,
secret,
});

user.companies = companies.filter(({ id }) => participantIds.has(id)).map(CompanyService.fixCompany);
}

return user;
} catch (e) {
if (!jwtData?.uid) {
return null;
}

return await UserService.infoBy("uid", jwtData.uid);
};
8 changes: 8 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
error,
ApiError,
} from "./helpers/route";
import EmailService from "./services/email-service";
import MobileNotificationService from "./services/mobile-notification-service";

const fileUploadMiddleware = fileUpload({
Expand All @@ -32,6 +33,8 @@ const fileUploadMiddleware = fileUpload({

const app = express();

app.set("trust proxy", true);

Sentry.init({ dsn: process.env.SENTRY_DSN });

// RequestHandler creates a separate execution context using domains, so that every
Expand Down Expand Up @@ -133,6 +136,11 @@ query(dbBase)
await client.end();
}
})
.then(async () => {
const result = await EmailService.verifyConnection();

console.log("|> EMAIL SERVICE:", result);
})
;

app.use((err, req, res, _next) => {
Expand Down
33 changes: 0 additions & 33 deletions api/routes/auth/login.js

This file was deleted.

73 changes: 73 additions & 0 deletions api/routes/auth/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import jwt from "jsonwebtoken";
import {
HttpStatus,
} from "../../helpers/http";
import {
ApiError,
Router,
} from "../../helpers/route";
import {
getJwtSecret,
} from "../../helpers/token";
import AuthService from "../../services/auth-service";
import UserLogService from "../../services/user-log-service";

const router = new Router();

router.post("/", async ({ body, ip, ips }, res) => {
const { email, password } = body;

if (!email || !password) {
throw new ApiError("no-credentials-provided");
}

const user = await AuthService.login(email, password);

if (!user) {
throw new ApiError(
"invalid-credentials",
HttpStatus.Error.Client.Unauthorized,
null,
);
}

const { uid } = user;

const payload = {
uid,
};

const token = jwt.sign(
payload,
getJwtSecret(),
{
expiresIn: "2 weeks",
},
);

res.cookie(
process.env.JOBFAIR_COOKIE_NAME,
JSON.stringify({
token,
}),
{
domain: `.${ new URL(process.env.BASE_URL || "").hostname }`,
expires: "",
secure: "development" !== process.env.NODE_ENV,
sameSite: "strict",
},
);

await UserLogService.log(
user.uid,
"login",
{
ip,
ips,
},
);

return user;
});

export default router;
Loading

0 comments on commit 7bac835

Please sign in to comment.