Add eslint rule and fix as many issues as possible

This commit is contained in:
Khoa Le
2023-06-19 23:42:04 -04:00
parent e9eacc445d
commit 9d33e4756b
689 changed files with 9446 additions and 21821 deletions
+50 -50
View File
@@ -1,29 +1,29 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import { Request, Response } from 'express';
import jwt from 'jsonwebtoken';
import * as Sentry from '@sentry/node';
import * as bigintConversion from 'bigint-conversion';
const jsrp = require('jsrp');
import { User, LoginSRPDetail } from '../../models';
import { issueAuthTokens, createToken, validateProviderAuthToken } from '../../helpers/auth';
import { checkUserDevice } from '../../helpers/user';
import { sendMail } from '../../helpers/nodemailer';
import { TokenService } from '../../services';
import { EELogService } from '../../ee/services';
import { BadRequestError, InternalServerError } from '../../utils/errors';
import { Request, Response } from "express";
import jwt from "jsonwebtoken";
import * as Sentry from "@sentry/node";
import * as bigintConversion from "bigint-conversion";
const jsrp = require("jsrp");
import { LoginSRPDetail, User } from "../../models";
import { createToken, issueAuthTokens, validateProviderAuthToken } from "../../helpers/auth";
import { checkUserDevice } from "../../helpers/user";
import { sendMail } from "../../helpers/nodemailer";
import { TokenService } from "../../services";
import { EELogService } from "../../ee/services";
import { BadRequestError, InternalServerError } from "../../utils/errors";
import {
ACTION_LOGIN,
TOKEN_EMAIL_MFA,
ACTION_LOGIN
} from '../../variables';
import { getChannelFromUserAgent } from '../../utils/posthog'; // TODO: move this
} from "../../variables";
import { getChannelFromUserAgent } from "../../utils/posthog"; // TODO: move this
import {
getHttpsEnabled,
getJwtMfaLifetime,
getJwtMfaSecret,
getHttpsEnabled,
} from '../../config';
import { AuthProvider } from '../../models/user';
} from "../../config";
import { AuthProvider } from "../../models/user";
declare module 'jsonwebtoken' {
declare module "jsonwebtoken" {
export interface ProviderAuthJwtPayload extends jwt.JwtPayload {
userId: string;
email: string;
@@ -43,7 +43,7 @@ export const login1 = async (req: Request, res: Response) => {
const {
email,
providerAuthToken,
clientPublicKey
clientPublicKey,
}: {
email: string;
clientPublicKey: string,
@@ -52,9 +52,9 @@ export const login1 = async (req: Request, res: Response) => {
const user = await User.findOne({
email,
}).select('+salt +verifier');
}).select("+salt +verifier");
if (!user) throw new Error('Failed to find user');
if (!user) throw new Error("Failed to find user");
if (user.authProvider) {
await validateProviderAuthToken({
@@ -68,13 +68,13 @@ export const login1 = async (req: Request, res: Response) => {
server.init(
{
salt: user.salt,
verifier: user.verifier
verifier: user.verifier,
},
async () => {
// generate server-side public key
const serverPublicKey = server.getPublicKey();
await LoginSRPDetail.findOneAndReplace({
email: email
email: email,
}, {
email,
userId: user.id,
@@ -84,7 +84,7 @@ export const login1 = async (req: Request, res: Response) => {
return res.status(200).send({
serverPublicKey,
salt: user.salt
salt: user.salt,
});
}
);
@@ -92,7 +92,7 @@ export const login1 = async (req: Request, res: Response) => {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to start authentication process'
message: "Failed to start authentication process",
});
}
};
@@ -107,15 +107,15 @@ export const login1 = async (req: Request, res: Response) => {
export const login2 = async (req: Request, res: Response) => {
try {
if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' });
if (!req.headers["user-agent"]) throw InternalServerError({ message: "User-Agent header is required" });
const { email, clientProof, providerAuthToken } = req.body;
const user = await User.findOne({
email,
}).select('+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices');
}).select("+salt +verifier +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag +publicKey +encryptedPrivateKey +iv +tag +devices");
if (!user) throw new Error('Failed to find user');
if (!user) throw new Error("Failed to find user");
if (user.authProvider) {
await validateProviderAuthToken({
@@ -136,7 +136,7 @@ export const login2 = async (req: Request, res: Response) => {
{
salt: user.salt,
verifier: user.verifier,
b: loginSRPDetail.serverBInt
b: loginSRPDetail.serverBInt,
},
async () => {
server.setClientPublicKey(loginSRPDetail.clientPublicKey);
@@ -150,52 +150,52 @@ export const login2 = async (req: Request, res: Response) => {
// generate temporary MFA token
const token = createToken({
payload: {
userId: user._id.toString()
userId: user._id.toString(),
},
expiresIn: await getJwtMfaLifetime(),
secret: await getJwtMfaSecret()
secret: await getJwtMfaSecret(),
});
const code = await TokenService.createToken({
type: TOKEN_EMAIL_MFA,
email
email,
});
// send MFA code [code] to [email]
await sendMail({
template: 'emailMfa.handlebars',
subjectLine: 'Infisical MFA code',
template: "emailMfa.handlebars",
subjectLine: "Infisical MFA code",
recipients: [user.email],
substitutions: {
code
}
code,
},
});
return res.status(200).send({
mfaEnabled: true,
token
token,
});
}
await checkUserDevice({
user,
ip: req.realIP,
userAgent: req.headers['user-agent'] ?? ''
userAgent: req.headers["user-agent"] ?? "",
});
// issue tokens
const tokens = await issueAuthTokens({
userId: user._id,
ip: req.realIP,
userAgent: req.headers['user-agent'] ?? ''
userAgent: req.headers["user-agent"] ?? "",
});
// store (refresh) token in httpOnly cookie
res.cookie('jid', tokens.refreshToken, {
res.cookie("jid", tokens.refreshToken, {
httpOnly: true,
path: '/',
sameSite: 'strict',
secure: await getHttpsEnabled()
path: "/",
sameSite: "strict",
secure: await getHttpsEnabled(),
});
// case: user does not have MFA enablgged
@@ -221,7 +221,7 @@ export const login2 = async (req: Request, res: Response) => {
publicKey: user.publicKey,
encryptedPrivateKey: user.encryptedPrivateKey,
iv: user.iv,
tag: user.tag
tag: user.tag,
}
if (
@@ -236,21 +236,21 @@ export const login2 = async (req: Request, res: Response) => {
const loginAction = await EELogService.createAction({
name: ACTION_LOGIN,
userId: user._id
userId: user._id,
});
loginAction && await EELogService.createLog({
userId: user._id,
actions: [loginAction],
channel: getChannelFromUserAgent(req.headers['user-agent']),
ipAddress: req.realIP
channel: getChannelFromUserAgent(req.headers["user-agent"]),
ipAddress: req.realIP,
});
return res.status(200).send(response);
}
return res.status(400).send({
message: 'Failed to authenticate. Try again?'
message: "Failed to authenticate. Try again?",
});
}
);
@@ -258,7 +258,7 @@ export const login2 = async (req: Request, res: Response) => {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to authenticate. Try again?'
message: "Failed to authenticate. Try again?",
});
}
};
+4 -4
View File
@@ -1,7 +1,7 @@
import * as secretsController from './secretsController';
import * as workspacesController from './workspacesController';
import * as authController from './authController';
import * as signupController from './signupController';
import * as secretsController from "./secretsController";
import * as workspacesController from "./workspacesController";
import * as authController from "./authController";
import * as signupController from "./signupController";
export {
authController,
+25 -25
View File
@@ -1,6 +1,6 @@
import { Request, Response } from "express";
import { Types } from "mongoose";
import { SecretService, EventService } from "../../services";
import { EventService, SecretService } from "../../services";
import { eventPushSecrets } from "../../events";
import { BotService } from "../../services";
import { repackageSecretToRaw } from "../../helpers/secrets";
@@ -25,18 +25,18 @@ export const getSecretsRaw = async (req: Request, res: Response) => {
});
const key = await BotService.getWorkspaceKeyWithBot({
workspaceId: new Types.ObjectId(workspaceId)
workspaceId: new Types.ObjectId(workspaceId),
});
return res.status(200).send({
secrets: secrets.map((secret) => {
const rep = repackageSecretToRaw({
secret,
key
key,
});
return rep;
})
}),
});
};
@@ -62,14 +62,14 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
});
const key = await BotService.getWorkspaceKeyWithBot({
workspaceId: new Types.ObjectId(workspaceId)
workspaceId: new Types.ObjectId(workspaceId),
});
return res.status(200).send({
secret: repackageSecretToRaw({
secret,
key
})
key,
}),
});
};
@@ -86,26 +86,26 @@ export const createSecretRaw = async (req: Request, res: Response) => {
type,
secretValue,
secretComment,
secretPath = "/"
secretPath = "/",
} = req.body;
const key = await BotService.getWorkspaceKeyWithBot({
workspaceId: new Types.ObjectId(workspaceId)
workspaceId: new Types.ObjectId(workspaceId),
});
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8({
plaintext: secretName,
key
key,
});
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8({
plaintext: secretValue,
key
key,
});
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8({
plaintext: secretComment,
key
key,
});
const secret = await SecretService.createSecret({
@@ -123,7 +123,7 @@ export const createSecretRaw = async (req: Request, res: Response) => {
secretPath,
secretCommentCiphertext: secretCommentEncrypted.ciphertext,
secretCommentIV: secretCommentEncrypted.iv,
secretCommentTag: secretCommentEncrypted.tag
secretCommentTag: secretCommentEncrypted.tag,
});
await EventService.handleEvent({
@@ -139,8 +139,8 @@ export const createSecretRaw = async (req: Request, res: Response) => {
return res.status(200).send({
secret: repackageSecretToRaw({
secret: secretWithoutBlindIndex,
key
})
key,
}),
});
}
@@ -160,12 +160,12 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => {
} = req.body;
const key = await BotService.getWorkspaceKeyWithBot({
workspaceId: new Types.ObjectId(workspaceId)
workspaceId: new Types.ObjectId(workspaceId),
});
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8({
plaintext: secretValue,
key
key,
});
const secret = await SecretService.updateSecret({
@@ -190,8 +190,8 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => {
return res.status(200).send({
secret: repackageSecretToRaw({
secret,
key
})
key,
}),
});
};
@@ -206,7 +206,7 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => {
workspaceId,
environment,
type,
secretPath = "/"
secretPath = "/",
} = req.body;
const { secret } = await SecretService.deleteSecret({
@@ -226,14 +226,14 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => {
});
const key = await BotService.getWorkspaceKeyWithBot({
workspaceId: new Types.ObjectId(workspaceId)
workspaceId: new Types.ObjectId(workspaceId),
});
return res.status(200).send({
secret: repackageSecretToRaw({
secret,
key
})
key,
}),
});
};
@@ -324,7 +324,7 @@ export const createSecret = async (req: Request, res: Response) => {
secretPath,
secretCommentCiphertext,
secretCommentIV,
secretCommentTag
secretCommentTag,
});
await EventService.handleEvent({
@@ -395,7 +395,7 @@ export const deleteSecretByName = async (req: Request, res: Response) => {
workspaceId,
environment,
type,
secretPath = "/"
secretPath = "/",
} = req.body;
const { secret } = await SecretService.deleteSecret({
+36 -36
View File
@@ -1,17 +1,17 @@
import jwt from 'jsonwebtoken';
import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { User, MembershipOrg } from '../../models';
import { completeAccount } from '../../helpers/user';
import jwt from "jsonwebtoken";
import { Request, Response } from "express";
import * as Sentry from "@sentry/node";
import { MembershipOrg, User } from "../../models";
import { completeAccount } from "../../helpers/user";
import {
initializeDefaultOrg
} from '../../helpers/signup';
import { issueAuthTokens, validateProviderAuthToken } from '../../helpers/auth';
import { INVITED, ACCEPTED } from '../../variables';
import { standardRequest } from '../../config/request';
import { getLoopsApiKey, getHttpsEnabled, getJwtSignupSecret } from '../../config';
import { BadRequestError } from '../../utils/errors';
import { TelemetryService } from '../../services';
initializeDefaultOrg,
} from "../../helpers/signup";
import { issueAuthTokens, validateProviderAuthToken } from "../../helpers/auth";
import { ACCEPTED, INVITED } from "../../variables";
import { standardRequest } from "../../config/request";
import { getHttpsEnabled, getJwtSignupSecret, getLoopsApiKey } from "../../config";
import { BadRequestError } from "../../utils/errors";
import { TelemetryService } from "../../services";
/**
* Complete setting up user by adding their personal and auth information as part of the
@@ -63,7 +63,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
// case 1: user doesn't exist.
// case 2: user has already completed account
return res.status(403).send({
error: 'Failed to complete account for complete user'
error: "Failed to complete account for complete user",
});
}
@@ -74,16 +74,16 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
user,
});
} else {
const [AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE] = <[string, string]>req.headers['authorization']?.split(' ', 2) ?? [null, null]
const [AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE] = <[string, string]>req.headers["authorization"]?.split(" ", 2) ?? [null, null]
if (AUTH_TOKEN_TYPE === null) {
throw BadRequestError({ message: `Missing Authorization Header in the request header.` });
throw BadRequestError({ message: "Missing Authorization Header in the request header." });
}
if (AUTH_TOKEN_TYPE.toLowerCase() !== 'bearer') {
if (AUTH_TOKEN_TYPE.toLowerCase() !== "bearer") {
throw BadRequestError({ message: `The provided authentication type '${AUTH_TOKEN_TYPE}' is not supported.` })
}
if (AUTH_TOKEN_VALUE === null) {
throw BadRequestError({
message: 'Missing Authorization Body in the request header',
message: "Missing Authorization Body in the request header",
})
}
@@ -110,16 +110,16 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
encryptedPrivateKeyIV,
encryptedPrivateKeyTag,
salt,
verifier
verifier,
});
if (!user)
throw new Error('Failed to complete account for non-existent user'); // ensure user is non-null
throw new Error("Failed to complete account for non-existent user"); // ensure user is non-null
// initialize default organization and workspace
await initializeDefaultOrg({
organizationName,
user
user,
});
// update organization membership statuses that are
@@ -127,11 +127,11 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
await MembershipOrg.updateMany(
{
inviteEmail: email,
status: INVITED
status: INVITED,
},
{
user,
status: ACCEPTED
status: ACCEPTED,
}
);
@@ -139,7 +139,7 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
const tokens = await issueAuthTokens({
userId: user._id,
ip: req.realIP,
userAgent: req.headers['user-agent'] ?? ''
userAgent: req.headers["user-agent"] ?? "",
});
token = tokens.token;
@@ -150,45 +150,45 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
"email": email,
"eventName": "Sign Up",
"firstName": firstName,
"lastName": lastName
"lastName": lastName,
}, {
headers: {
"Accept": "application/json",
"Authorization": "Bearer " + (await getLoopsApiKey())
"Authorization": "Bearer " + (await getLoopsApiKey()),
},
});
}
// store (refresh) token in httpOnly cookie
res.cookie('jid', tokens.refreshToken, {
res.cookie("jid", tokens.refreshToken, {
httpOnly: true,
path: '/',
sameSite: 'strict',
secure: await getHttpsEnabled()
path: "/",
sameSite: "strict",
secure: await getHttpsEnabled(),
});
const postHogClient = await TelemetryService.getPostHogClient();
if (postHogClient) {
postHogClient.capture({
event: 'User Signed Up',
event: "User Signed Up",
distinctId: email,
properties: {
email,
attributionSource
}
attributionSource,
},
});
}
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to complete account setup'
message: "Failed to complete account setup",
});
}
return res.status(200).send({
message: 'Successfully set up account',
message: "Successfully set up account",
user,
token
token,
});
};
@@ -1,7 +1,7 @@
import { Request, Response } from 'express';
import { Types } from 'mongoose';
import { Secret } from '../../models';
import { SecretService } from'../../services';
import { Request, Response } from "express";
import { Types } from "mongoose";
import { Secret } from "../../models";
import { SecretService } from"../../services";
/**
* Return whether or not all secrets in workspace with id [workspaceId]
@@ -16,8 +16,8 @@ export const getWorkspaceBlindIndexStatus = async (req: Request, res: Response)
const secretsWithoutBlindIndex = await Secret.countDocuments({
workspace: new Types.ObjectId(workspaceId),
secretBlindIndex: {
$exists: false
}
$exists: false,
},
});
return res.status(200).send(secretsWithoutBlindIndex === 0);
@@ -30,11 +30,11 @@ export const getWorkspaceSecrets = async (req: Request, res: Response) => {
const { workspaceId } = req.params;
const secrets = await Secret.find({
workspace: new Types.ObjectId (workspaceId)
workspace: new Types.ObjectId (workspaceId),
});
return res.status(200).send({
secrets
secrets,
});
}
@@ -51,14 +51,14 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => {
const { workspaceId } = req.params;
const {
secretsToUpdate
secretsToUpdate,
}: {
secretsToUpdate: SecretToUpdate[];
} = req.body;
// get secret blind index salt
const salt = await SecretService.getSecretBlindIndexSalt({
workspaceId: new Types.ObjectId(workspaceId)
workspaceId: new Types.ObjectId(workspaceId),
});
// update secret blind indices
@@ -66,18 +66,18 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => {
secretsToUpdate.map(async (secretToUpdate: SecretToUpdate) => {
const secretBlindIndex = await SecretService.generateSecretBlindIndexWithSalt({
secretName: secretToUpdate.secretName,
salt
salt,
});
return ({
updateOne: {
filter: {
_id: new Types.ObjectId(secretToUpdate._id)
_id: new Types.ObjectId(secretToUpdate._id),
},
update: {
secretBlindIndex
}
}
secretBlindIndex,
},
},
});
})
);
@@ -85,6 +85,6 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => {
await Secret.bulkWrite(operations);
return res.status(200).send({
message: 'Successfully named workspace secrets'
message: "Successfully named workspace secrets",
});
}