-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #619 from CodeForAfrica/fix/codeforafrica_cms
Review of @/codeforafrica CMS
- Loading branch information
Showing
56 changed files
with
1,039 additions
and
574 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,16 +2,18 @@ import path from "path"; | |
import { spawn } from "child_process"; | ||
import express from "express"; | ||
import next from "next"; | ||
import nodemailerSendgrid from "nodemailer-sendgrid"; | ||
import payload from "payload"; | ||
import { Payload } from "payload/dist/payload"; | ||
import { loadEnvConfig } from "@next/env"; | ||
|
||
const projectDir = process.cwd(); | ||
loadEnvConfig(projectDir); | ||
|
||
const hostname = process.env.NEXT_HOSTNAME || "localhost"; | ||
const PORT = parseInt(process.env.PORT || "3000", 10); | ||
const dev = process.env.NODE_ENV !== "production"; | ||
const hostname = process.env.NEXT_HOSTNAME || "localhost"; | ||
const port = parseInt(process.env.PORT || "3000", 10); | ||
const sendGridAPIKey = process.env.SENDGRID_API_KEY; | ||
|
||
if (!process.env.NEXT_MANUAL_SIG_HANDLE) { | ||
process.on("SIGTERM", () => process.exit(0)); | ||
|
@@ -24,6 +26,18 @@ const start = async (): Promise<void> => { | |
let localPayload: Payload; | ||
try { | ||
localPayload = await payload.init({ | ||
...(sendGridAPIKey | ||
? { | ||
email: { | ||
transportOptions: nodemailerSendgrid({ | ||
apiKey: sendGridAPIKey, | ||
}), | ||
fromName: process.env.SENDGRID_FROM_NAME || "Code for Africa CMS", | ||
fromAddress: | ||
process.env.SENDGRID_FROM_EMAIL || "[email protected]", | ||
}, | ||
} | ||
: undefined), | ||
secret: process.env.PAYLOAD_SECRET, | ||
mongoURL: process.env.MONGODB_URL, | ||
express: app, | ||
|
@@ -37,7 +51,7 @@ const start = async (): Promise<void> => { | |
} | ||
|
||
if (process.env.NEXT_BUILD) { | ||
app.listen(PORT, async () => { | ||
app.listen(port, async () => { | ||
localPayload.logger.info("NextJS is now building..."); | ||
const nextBuild = spawn( | ||
"pnpm", | ||
|
@@ -50,7 +64,6 @@ const start = async (): Promise<void> => { | |
nextBuild.on("close", (code) => { | ||
process.exit(code); | ||
}); | ||
|
||
nextBuild.on("error", (err) => { | ||
localPayload.logger.error(err); | ||
process.exit(1); | ||
|
@@ -60,7 +73,7 @@ const start = async (): Promise<void> => { | |
return; | ||
} | ||
|
||
const nextApp = next({ dev, hostname, port: PORT }); | ||
const nextApp = next({ dev, hostname, port }); | ||
const nextHandler = nextApp.getRequestHandler(); | ||
nextApp.prepare().then(() => { | ||
localPayload.logger.info("NextJS started"); | ||
|
@@ -69,7 +82,7 @@ const start = async (): Promise<void> => { | |
app.post("*", (req: any, res: any) => nextHandler(req, res)); | ||
app.put("*", (req: any, res: any) => nextHandler(req, res)); | ||
|
||
app.listen(PORT, async () => { | ||
app.listen(port, async () => { | ||
localPayload.logger.info( | ||
`Next.js App URL: ${process.env.NEXT_PUBLIC_APP_URL}`, | ||
); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// By default, the Draft Mode session ends when the browser is closed. | ||
// This method clears it manually / on demand. | ||
export default function handler(req, res) { | ||
res.setDraftMode({ enable: false }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export default async function handler(req, res) { | ||
// Since payload and Next.js are running on the same server process, lets | ||
// make sure the user requesting to preview, is logged into Payload | ||
// See "Tip" on: https://payloadcms.com/docs/authentication/overview#token-based-auth | ||
if (!req.user) { | ||
return res.status(401).json({ message: "UNAUTHORIZED_USER" }); | ||
} | ||
const { slug } = req.query; | ||
res.setDraftMode({ enable: true }); | ||
|
||
// Guard against open redirect vulnerabilities | ||
// Since slug will be a path, redirect to pathname instead of original slug | ||
// just in case | ||
const appUrl = new URL(process.env.NEXT_PUBLIC_APP_URL); | ||
const requestedUrl = new URL(slug, appUrl); | ||
if (requestedUrl.origin !== appUrl.origin) { | ||
return res.status(401).json({ message: "UNAUTHORIZED_REDIRECT" }); | ||
} | ||
return res.redirect(requestedUrl.pathname); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { ROLE_ADMIN } from "./roles"; | ||
|
||
export const isAdmin = ({ req: { user } }) => { | ||
// Return true or false based on if the user has an admin role | ||
return Boolean(user?.roles?.includes(ROLE_ADMIN)); | ||
}; | ||
|
||
export const isAdminFieldLevel = ({ req: { user } }) => { | ||
// Return true or false based on if the user has an admin role | ||
return Boolean(user?.roles?.includes(ROLE_ADMIN)); | ||
}; |
14 changes: 14 additions & 0 deletions
14
apps/codeforafrica/src/payload/access/isAdminOrPublished.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { ROLE_ADMIN } from "./roles"; | ||
|
||
export const isAdminOrPublished = ({ req: { user } }) => { | ||
if (user?.roles?.includes(ROLE_ADMIN)) { | ||
return true; | ||
} | ||
return { | ||
_status: { | ||
equals: "published", | ||
}, | ||
}; | ||
}; | ||
|
||
export default undefined; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ROLE_ADMIN } from "./roles"; | ||
|
||
export const isAdminOrSelf = ({ req: { user } }) => { | ||
// Need to be logged in | ||
if (user) { | ||
// If user has role of 'admin' | ||
if (user.roles?.includes(ROLE_ADMIN)) { | ||
return true; | ||
} | ||
// If any other type of user, only provide access to themselves | ||
return { | ||
id: { | ||
equals: user.id, | ||
}, | ||
}; | ||
} | ||
|
||
// Reject everyone else | ||
return false; | ||
}; | ||
|
||
export const isAdminOrSelfFieldLevel = ({ id, req: { user } }) => { | ||
return user?.roles?.includes(ROLE_ADMIN) || id === user?.id; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export const ROLE_ADMIN = "admin"; | ||
export const ROLE_EDITOR = "editor"; | ||
export const ROLE_DEFAULT = ROLE_EDITOR; | ||
export const ROLE_OPTIONS = [ | ||
{ label: "Admin", value: ROLE_ADMIN }, | ||
{ label: "Editor", value: ROLE_EDITOR }, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.