Skip to content

Commit

Permalink
Various bug fixes and error handling improvements (growthbook#618)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdorn authored Oct 9, 2022
1 parent 47fce5d commit 5cefb86
Show file tree
Hide file tree
Showing 47 changed files with 636 additions and 386 deletions.
7 changes: 4 additions & 3 deletions packages/back-end/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ type Controller<T extends string> = Record<T, Handler>;

// Wrap every controller function in asyncHandler to catch errors properly
function wrapController<T extends string>(
controller: Controller<T>
// eslint-disable-next-line
controller: Record<T, any>
): Controller<T> {
const newController = {} as Controller<T>;
Object.keys(controller).forEach((key: T) => {
Expand Down Expand Up @@ -284,7 +285,7 @@ app.get(
getExperimentConfig
);
app.get(
"/api/features/:key",
"/api/features/:key?",
cors({
credentials: false,
origin: "*",
Expand All @@ -293,7 +294,7 @@ app.get(
);
// For preflight requests
app.options(
"/api/features/:key",
"/api/features/:key?",
cors({
credentials: false,
origin: "*",
Expand Down
7 changes: 5 additions & 2 deletions packages/back-end/src/controllers/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,18 @@ export async function getOrganizations(req: AuthRequest, res: Response) {
});
}

export async function addSampleData(req: AuthRequest, res: Response) {
export async function addSampleData(
req: AuthRequest<unknown, { id: string }>,
res: Response
) {
if (!req.admin) {
return res.status(403).json({
status: 403,
message: "Only admins can perform this action",
});
}

const { id }: { id: string } = req.params;
const { id } = req.params;

const org = await findOrganizationById(id);
if (!org) {
Expand Down
34 changes: 21 additions & 13 deletions packages/back-end/src/controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,30 @@ export async function postRefresh(req: Request, res: Response) {
}

export async function postOAuthCallback(req: Request, res: Response) {
const { idToken, refreshToken, expiresIn } = await auth.processCallback(
req,
res,
null
);
try {
const { idToken, refreshToken, expiresIn } = await auth.processCallback(
req,
res,
null
);

if (!idToken) {
throw new Error("Could not authenticate");
}
if (!idToken) {
throw new Error("Could not authenticate");
}

RefreshTokenCookie.setValue(refreshToken, req, res);
IdTokenCookie.setValue(idToken, req, res, expiresIn);
RefreshTokenCookie.setValue(refreshToken, req, res);
IdTokenCookie.setValue(idToken, req, res, expiresIn);

return res.status(200).json({
status: 200,
});
return res.status(200).json({
status: 200,
});
} catch (e) {
console.error(e);
return res.status(400).json({
status: 400,
message: "Error Signing In",
});
}
}

async function sendLocalSuccessResponse(
Expand Down
26 changes: 21 additions & 5 deletions packages/back-end/src/controllers/experiments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,16 @@ import {
auditDetailsDelete,
} from "../services/audit";

export async function getExperiments(req: AuthRequest, res: Response) {
export async function getExperiments(
req: AuthRequest<
unknown,
unknown,
{
project?: string;
}
>,
res: Response
) {
const { org } = getOrgFromReq(req);
let project = "";
if (typeof req.query?.project === "string") {
Expand All @@ -74,7 +83,7 @@ export async function getExperiments(req: AuthRequest, res: Response) {
}

export async function getExperimentsFrequencyMonth(
req: AuthRequest<null, { num: string }>,
req: AuthRequest<null, { num: string }, { project?: string }>,
res: Response
) {
const { org } = getOrgFromReq(req);
Expand Down Expand Up @@ -255,7 +264,10 @@ export async function postSnapshotNotebook(
});
}

export async function getSnapshots(req: AuthRequest, res: Response) {
export async function getSnapshots(
req: AuthRequest<unknown, unknown, { ids?: string }>,
res: Response
) {
const { org } = getOrgFromReq(req);
const idsString = (req.query?.ids as string) || "";
if (!idsString.length) {
Expand All @@ -281,7 +293,10 @@ export async function getSnapshots(req: AuthRequest, res: Response) {
return;
}

export async function getNewFeatures(req: AuthRequest, res: Response) {
export async function getNewFeatures(
req: AuthRequest<unknown, unknown, { project?: string }>,
res: Response
) {
const { org } = getOrgFromReq(req);
let project = "";
if (typeof req.query?.project === "string") {
Expand Down Expand Up @@ -1362,7 +1377,8 @@ export async function postSnapshot(
users?: number[];
metrics?: { [key: string]: MetricStats[] };
},
{ id: string }
{ id: string },
{ force?: string }
>,
res: Response
) {
Expand Down
12 changes: 11 additions & 1 deletion packages/back-end/src/controllers/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ import { getRevisions } from "../models/FeatureRevisionModel";
export async function getFeaturesPublic(req: Request, res: Response) {
const { key } = req.params;

if (!key) {
return res.status(400).json({
status: 400,
error: "Missing API key",
});
}

let project = "";
if (typeof req.query?.project === "string") {
project = req.query.project;
Expand Down Expand Up @@ -568,7 +575,10 @@ export async function postFeatureArchive(
});
}

export async function getFeatures(req: AuthRequest, res: Response) {
export async function getFeatures(
req: AuthRequest<unknown, unknown, { project?: string }>,
res: Response
) {
const { org } = getOrgFromReq(req);

let project = "";
Expand Down
6 changes: 3 additions & 3 deletions packages/back-end/src/controllers/ideas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ export async function postIdeas(
}

export async function getIdea(
req: AuthRequest<Partial<IdeaInterface>>,
req: AuthRequest<Partial<IdeaInterface>, { id: string }>,
res: Response
) {
const { id }: { id: string } = req.params;
const { id } = req.params;
//const data = req.body;

const idea = await getIdeaById(id);
Expand Down Expand Up @@ -332,7 +332,7 @@ export async function postVote(
}

export async function getRecentIdeas(
req: AuthRequest<null, { num: string }>,
req: AuthRequest<unknown, { num: string }, { project?: string }>,
res: Response
) {
const { org } = getOrgFromReq(req);
Expand Down
35 changes: 27 additions & 8 deletions packages/back-end/src/controllers/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,10 @@ export async function deleteNamespace(
});
}

export async function postInviteAccept(req: AuthRequest, res: Response) {
export async function postInviteAccept(
req: AuthRequest<{ key: string }>,
res: Response
) {
const { key } = req.body;

try {
Expand All @@ -775,7 +778,13 @@ export async function postInviteAccept(req: AuthRequest, res: Response) {
}
}

export async function postInvite(req: AuthRequest, res: Response) {
export async function postInvite(
req: AuthRequest<{
email: string;
role: MemberRole;
}>,
res: Response
) {
req.checkPermissions("organizationSettings");

const { org } = getOrgFromReq(req);
Expand Down Expand Up @@ -1107,11 +1116,16 @@ export async function deleteWebhook(
});
}

export async function postImportConfig(req: AuthRequest, res: Response) {
export async function postImportConfig(
req: AuthRequest<{
contents: string;
}>,
res: Response
) {
req.checkPermissions("organizationSettings");

const { org } = getOrgFromReq(req);
const { contents }: { contents: string } = req.body;
const { contents } = req.body;

const config: ConfigFile = JSON.parse(contents);
if (!config) {
Expand All @@ -1135,10 +1149,15 @@ export async function putUpload(req: Request, res: Response) {
}

export async function putAdminResetUserPassword(
req: AuthRequest<{
userToUpdateId: string;
updatedPassword: string;
}>,
req: AuthRequest<
{
userToUpdateId: string;
updatedPassword: string;
},
{
id: string;
}
>,
res: Response
) {
req.checkPermissions("organizationSettings");
Expand Down
18 changes: 15 additions & 3 deletions packages/back-end/src/controllers/reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,16 @@ export async function postReportFromSnapshot(
});
}

export async function getReports(req: AuthRequest, res: Response) {
export async function getReports(
req: AuthRequest<
unknown,
unknown,
{
project?: string;
}
>,
res: Response
) {
const { org } = getOrgFromReq(req);
let project = "";
if (typeof req.query?.project === "string") {
Expand Down Expand Up @@ -116,7 +125,10 @@ export async function getReports(req: AuthRequest, res: Response) {
});
}

export async function getReportsOnExperiment(req: AuthRequest, res: Response) {
export async function getReportsOnExperiment(
req: AuthRequest<unknown, { id: string }>,
res: Response
) {
const { org } = getOrgFromReq(req);
const { id } = req.params;

Expand Down Expand Up @@ -172,7 +184,7 @@ export async function deleteReport(
}

export async function refreshReport(
req: AuthRequest<null, { id: string }>,
req: AuthRequest<null, { id: string }, { force?: string }>,
res: Response
) {
req.checkPermissions("runQueries");
Expand Down
2 changes: 1 addition & 1 deletion packages/back-end/src/controllers/segments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function postSegments(
});
}
export async function putSegment(
req: AuthRequest<Partial<SegmentInterface>>,
req: AuthRequest<Partial<SegmentInterface>, { id: string }>,
res: Response
) {
req.checkPermissions("createSegments");
Expand Down
2 changes: 1 addition & 1 deletion packages/back-end/src/controllers/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function postTag(req: AuthRequest<TagInterface>, res: Response) {
}

export async function deleteTag(
req: AuthRequest<{ id: string }>,
req: AuthRequest<{ id: string }, { id: string }>,
res: Response
) {
req.checkPermissions("organizationSettings");
Expand Down
Loading

0 comments on commit 5cefb86

Please sign in to comment.