-
Notifications
You must be signed in to change notification settings - Fork 35
Projects integration #2057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Projects integration #2057
Changes from all commits
79ebe9d
0785051
aaa9a3d
715d61d
88ba35d
09e50d1
8bb0cfa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| import { Request, RequestHandler, Router } from "express"; | ||
| import { authorizer, validatePost } from "../middleware"; | ||
| import { db } from "../store"; | ||
| import { v4 as uuid } from "uuid"; | ||
| import { | ||
| makeNextHREF, | ||
| parseFilters, | ||
| parseOrder, | ||
| getS3PresignedUrl, | ||
| toStringValues, | ||
| pathJoin, | ||
| getObjectStoreS3Config, | ||
| reqUseReplica, | ||
| isValidBase64, | ||
| mapInputCreatorId, | ||
| } from "./helpers"; | ||
| import sql from "sql-template-strings"; | ||
| import { | ||
| ForbiddenError, | ||
| UnprocessableEntityError, | ||
| NotFoundError, | ||
| BadRequestError, | ||
| InternalServerError, | ||
| UnauthorizedError, | ||
| NotImplementedError, | ||
| } from "../store/errors"; | ||
|
|
||
| const app = Router(); | ||
|
|
||
| export async function getProject(req) { | ||
| const projectId = req.params.projectId || req.body.projectId; | ||
| console.log("XXX: getting project:", projectId); | ||
|
|
||
| const project = await db.project.get(projectId); | ||
| if (!project || project.deleted) { | ||
| throw new NotFoundError(`project not found`); | ||
| } | ||
|
|
||
| if (!req.user.admin && req.user.id !== project.userId) { | ||
| throw new ForbiddenError(`invalid user`); | ||
| } | ||
|
|
||
| return project; | ||
| } | ||
|
|
||
| const fieldsMap = { | ||
| id: `project.ID`, | ||
| name: { val: `project.data->>'name'`, type: "full-text" }, | ||
| createdAt: { val: `project.data->'createdAt'`, type: "int" }, | ||
| userId: `project.data->>'userId'`, | ||
| } as const; | ||
|
|
||
| app.get("/", authorizer({}), async (req, res) => { | ||
Check failureCode scanning / CodeQL Missing rate limiting
This route handler performs [authorization](1), but is not rate-limited.
|
||
| let { limit, cursor, order, all, filters, count } = toStringValues(req.query); | ||
|
|
||
| if (isNaN(parseInt(limit))) { | ||
| limit = undefined; | ||
| } | ||
| if (!order) { | ||
| order = "updatedAt-true,createdAt-true"; | ||
| } | ||
|
|
||
| const query = [...parseFilters(fieldsMap, filters)]; | ||
|
|
||
| if (!req.user.admin || !all || all === "false") { | ||
| query.push(sql`project.data->>'deleted' IS NULL`); | ||
| } | ||
|
|
||
| let output: WithID<Project>[]; | ||
| let newCursor: string; | ||
| if (req.user.admin) { | ||
| let fields = | ||
| " project.id as id, project.data as data, users.id as usersId, users.data as usersdata"; | ||
| if (count) { | ||
| fields = fields + ", count(*) OVER() AS count"; | ||
| } | ||
| const from = `project left join users on project.data->>'userId' = users.id`; | ||
| [output, newCursor] = await db.project.find(query, { | ||
| limit, | ||
| cursor, | ||
| fields, | ||
| from, | ||
| order: parseOrder(fieldsMap, order), | ||
| process: ({ data, usersdata, count: c }) => { | ||
| if (count) { | ||
| res.set("X-Total-Count", c); | ||
| } | ||
| return { | ||
| ...data, | ||
| user: db.user.cleanWriteOnlyResponse(usersdata), | ||
| }; | ||
| }, | ||
| }); | ||
| } else { | ||
| query.push(sql`project.data->>'userId' = ${req.user.id}`); | ||
|
|
||
| let fields = " project.id as id, project.data as data"; | ||
| if (count) { | ||
| fields = fields + ", count(*) OVER() AS count"; | ||
| } | ||
| [output, newCursor] = await db.project.find(query, { | ||
| limit, | ||
| cursor, | ||
| fields, | ||
| order: parseOrder(fieldsMap, order), | ||
| process: ({ data, count: c }) => { | ||
| if (count) { | ||
| res.set("X-Total-Count", c); | ||
| } | ||
| return data; | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| res.status(200); | ||
| if (output.length > 0 && newCursor) { | ||
| res.links({ next: makeNextHREF(req, newCursor) }); | ||
| } | ||
|
|
||
| return res.json(output); | ||
| }); | ||
|
|
||
| app.get("/:projectId", authorizer({}), async (req, res) => { | ||
Check failureCode scanning / CodeQL Missing rate limiting
This route handler performs [authorization](1), but is not rate-limited.
|
||
| const project = await getProject(req); | ||
|
|
||
| if (!project) { | ||
| res.status(403); | ||
| return res.json({ errors: ["project not found"] }); | ||
| } | ||
|
|
||
| res.status(200); | ||
| res.json(project); | ||
| }); | ||
|
|
||
| app.post("/", authorizer({}), async (req, res) => { | ||
Check failureCode scanning / CodeQL Missing rate limiting
This route handler performs [authorization](1), but is not rate-limited.
|
||
| const { name } = req.body; | ||
|
|
||
| console.log("XXX: req.user", req.user); | ||
| console.log("XXX: req.query", req.query); | ||
|
|
||
| const id = uuid(); | ||
| await db.project.create({ | ||
| id: id, | ||
| name: name, | ||
| userId: req.user.id, | ||
| createdAt: Date.now(), | ||
| }); | ||
| res.status(201); | ||
|
|
||
| const project = await db.project.get(id, { useReplica: false }); | ||
|
|
||
| if (!project) { | ||
| res.status(403); | ||
| return res.json({ errors: ["project not created"] }); | ||
| } | ||
|
|
||
| res.status(201); | ||
| res.json(id); | ||
| }); | ||
|
|
||
| export default app; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { Request, RequestHandler, Router } from "express"; | ||
| import { authorizer, validatePost } from "../middleware"; | ||
| import { db } from "../store"; | ||
| import { v4 as uuid } from "uuid"; | ||
|
|
||
| const app = Router(); | ||
|
|
||
| app.get("/", authorizer({}), async (req, res) => { | ||
Check failureCode scanning / CodeQL Missing rate limiting
This route handler performs [authorization](1), but is not rate-limited.
|
||
| res.status(200); | ||
| res.json({}); | ||
| }); | ||
|
|
||
| app.post("/", authorizer({}), async (req, res) => { | ||
Check failureCode scanning / CodeQL Missing rate limiting
This route handler performs [authorization](1), but is not rate-limited.
|
||
| const { name } = req.body; | ||
|
|
||
| const id = uuid(); | ||
| await db.workspace.create({ | ||
| id: id, | ||
| name: "foo", | ||
| userId: req.user.id, | ||
| createdAt: Date.now(), | ||
| }); | ||
| res.status(201).end(); | ||
| }); | ||
|
|
||
| export default app; | ||
Uh oh!
There was an error while loading. Please reload this page.