-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add express recipe for
@edgedb/create
(#826)
- Loading branch information
1 parent
6fd983f
commit 95cde2b
Showing
7 changed files
with
235 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { type NextFunction, type Response, Router } from "express"; | ||
import createExpressAuth, { | ||
type AuthRequest, | ||
type CallbackRequest, | ||
} from "@edgedb/auth-express"; | ||
import { client } from "./db.js"; | ||
import { PORT } from "./env.js"; | ||
|
||
export const auth = createExpressAuth(client, { | ||
baseUrl: `http://localhost:${PORT}`, | ||
}); | ||
|
||
export const requireAuth = async ( | ||
req: AuthRequest, | ||
res: Response, | ||
next: NextFunction | ||
) => { | ||
if (!(await req.session?.isSignedIn())) { | ||
res.redirect("/signin"); | ||
} else { | ||
next(); | ||
} | ||
}; | ||
|
||
/************ | ||
* Sign Out * | ||
************/ | ||
|
||
export const signoutRoute = Router().get( | ||
"/", | ||
auth.signout, | ||
async (_: AuthRequest, res: Response) => { | ||
res.redirect("/"); | ||
} | ||
); | ||
|
||
/*************** | ||
* Built-in UI * | ||
***************/ | ||
|
||
const builtinCallback = async (req: CallbackRequest, res: Response) => { | ||
if (req.isSignUp) { | ||
return res.redirect("/onboarding"); | ||
} | ||
|
||
res.redirect("/"); | ||
}; | ||
|
||
export const builtinUIRouter = auth.createBuiltinRouter({ | ||
callback: [builtinCallback], | ||
}); |
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,3 @@ | ||
import { createClient } from "edgedb"; | ||
|
||
export const client = createClient(); |
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 @@ | ||
export const PORT = process.env.PORT || 3333; |
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,76 @@ | ||
import express from "express"; | ||
import cookieParser from "cookie-parser"; | ||
import { type AuthRequest } from "@edgedb/auth-express"; | ||
|
||
import { styles } from "./styles.js"; | ||
import { auth, requireAuth, signoutRoute, builtinUIRouter } from "./auth.js"; | ||
import { PORT } from "./env.js"; | ||
|
||
const app = express(); | ||
|
||
app.use(express.json()); | ||
app.use(express.urlencoded({ extended: false })); | ||
app.use(cookieParser()); | ||
app.use(auth.createSessionMiddleware()); | ||
|
||
router.get("/api/deep-thought", requireAuth, async (req: AuthRequest, res) => { | ||
// See more examples of making queries here: https://github.com/edgedb/edgedb-examples/blob/main/express-auth/todos.ts | ||
const answer = await req.session!.client.query<number>("select 42;"); | ||
res.json(answer); | ||
}); | ||
|
||
app.use("/auth", builtinUIRouter); | ||
app.use("/auth/signout", signoutRoute); | ||
|
||
const pageTemplate = (body: string) => ` | ||
<html> | ||
<head> | ||
<style> | ||
${styles} | ||
</style> | ||
</head> | ||
<body> | ||
<main> | ||
${body} | ||
</main> | ||
</body> | ||
</html> | ||
`; | ||
|
||
app.get("/onboarding", requireAuth, (req, res) => { | ||
res.send( | ||
pageTemplate(` | ||
<h1>Onboarding</h1> | ||
<a href="/auth/signout">Sign out</a> | ||
`) | ||
); | ||
}); | ||
|
||
app.get("/dashboard", requireAuth, (req, res) => { | ||
res.send( | ||
pageTemplate(` | ||
<h1>Dashboard</h1> | ||
<a href="/auth/signout">Sign out</a> | ||
`) | ||
); | ||
}); | ||
|
||
app.get("/verify", (req, res) => { | ||
res.send( | ||
pageTemplate(` | ||
<p>Check your email for a verification message.</p> | ||
`) | ||
); | ||
}); | ||
|
||
app.get("/signin", (_, res) => { | ||
res.redirect("/auth/signin"); | ||
}); | ||
|
||
app.get("/", requireAuth, async (req: AuthRequest, res) => { | ||
res.redirect("/dashboard"); | ||
}); | ||
|
||
app.listen(PORT, () => { | ||
console.log(`Listening on http://localhost:${PORT}`); | ||
}); |
68 changes: 68 additions & 0 deletions
68
packages/create/src/recipes/express/template/src/styles.ts
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,68 @@ | ||
export const styles = ` | ||
body { | ||
font-family: Arial, sans-serif; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
main { | ||
max-width: 600px; | ||
margin: 0 auto; | ||
padding: 20px; | ||
} | ||
h1 { | ||
color: #333; | ||
} | ||
a { | ||
color: #0066cc; | ||
} | ||
.errors { | ||
margin-bottom: 20px; | ||
display: flex; | ||
flex-direction: column; | ||
gap: 5px; | ||
} | ||
.errors:empty { | ||
display: none; | ||
} | ||
p.error { | ||
display: block; | ||
padding: 10px; | ||
background-color: #ffcccc; | ||
color: #cc0000; | ||
} | ||
.form-control { | ||
margin-bottom: 10px; | ||
width: 100%; | ||
} | ||
label { | ||
display: block; | ||
margin-bottom: 5px; | ||
} | ||
input { | ||
width: 100%; | ||
padding: 10px; | ||
margin-bottom: 10px; | ||
} | ||
.actions { | ||
display: flex; | ||
align-items: center; | ||
gap: 5px; | ||
} | ||
button[type="submit"] { | ||
padding: 10px 20px; | ||
background-color: #0066cc; | ||
color: #fff; | ||
border: none; | ||
} | ||
`; |