Skip to content

Commit

Permalink
Reference the Copenhagen Book in docs (#1479)
Browse files Browse the repository at this point in the history
  • Loading branch information
pilcrowonpaper authored Mar 10, 2024
1 parent 052e6b2 commit 64df574
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 18 deletions.
2 changes: 2 additions & 0 deletions docs/pages/getting-started/astro.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,6 @@ declare namespace App {

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
2 changes: 2 additions & 0 deletions docs/pages/getting-started/express.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ node --experimental-web-crypto index.js

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
4 changes: 4 additions & 0 deletions docs/pages/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ module.exports = {
externals: ["@node-rs/argon2", "@node-rs/bcrypt"]
};
```

## The Copenhagen Book

This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.
4 changes: 3 additions & 1 deletion docs/pages/getting-started/nextjs-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,6 @@ Currently, `oslo/password` cannot be used with Turbopack.

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
5 changes: 4 additions & 1 deletion docs/pages/getting-started/nextjs-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,7 @@ export async function middleware(request: NextRequest): Promise<NextResponse> {

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.


If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
2 changes: 2 additions & 0 deletions docs/pages/getting-started/nuxt.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,6 @@ declare module "h3" {

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
2 changes: 2 additions & 0 deletions docs/pages/getting-started/solidstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,6 @@ export default defineConfig({

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
2 changes: 2 additions & 0 deletions docs/pages/getting-started/sveltekit.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,6 @@ export {};

You can learn all the concepts and APIs by reading the [Basics section](/basics/sessions) in the docs. If you prefer writing code immediately, check out the [Tutorials](/tutorials) page or the [examples repository](https://github.com/lucia-auth/examples/tree/main).

This documentation often references [the Copenhagen Book](https://thecopenhagenbook.com/mfa). This is an open-source guide on implementing auth and should come in handy when implementing anything auth, including passkeys, multi-factor authentication, and a bit of cryptography. We recommend reading it to learn more about auth in web applications.

If you have any questions, [join our Discord server](https://discord.com/invite/PwrK3kpVR3)!
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ title: "Email verification codes"

# Email verification codes

We recommend reading through the [email verification guide](https://thecopenhagenbook.com/email-verification) in the Copenhagen Book.

## Update database

### User table
Expand Down
11 changes: 9 additions & 2 deletions docs/pages/guides/email-and-password/email-verification-links.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ title: "Email verification links"

# Email verification links

We recommend using [email verification codes](/guides/email-and-password/email-verification-codes) instead as it's more user-friendly.
Email verification works by storing a secret token inside a link. The user's email address is verified when they visit the link.

```
https://example.com/email-verification/<TOKEN>
```

We recommend using [email verification codes](/guides/email-and-password/email-verification-codes) instead as it's more user-friendly. We also recommend reading through the [email verification guide](https://thecopenhagenbook.com/email-verification) in the Copenhagen Book.

## Update database

Expand Down Expand Up @@ -153,7 +159,8 @@ app.get("email-verification/:token", async () => {
status: 302,
headers: {
Location: "/",
"Set-Cookie": sessionCookie.serialize()
"Set-Cookie": sessionCookie.serialize(),
"Referrer-Policy": "no-referrer"
}
});
});
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/guides/email-and-password/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ Email-based auth requires a lot of components so be prepared to do some work! Fo
- [Password reset](/guides/email-and-password/password-reset)
- [Login throttling](/guides/email-and-password/login-throttling)
- [Two-factor authorization](/guides/email-and-password/2fa)

We recommend reading through the [password authentication guide](https://thecopenhagenbook.com/password-authentication) in the Copenhagen Book.
51 changes: 38 additions & 13 deletions docs/pages/guides/email-and-password/password-reset.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,35 @@ title: "Password reset"

Allow users to reset their password by sending them a reset link to their inbox.

We recommend reading through the [password reset guide](https://thecopenhagenbook.com/password-reset) in the Copenhagen Book.

## Update database

Create a table for storing for password reset tokens.

| column | type | attributes |
| ------------ | -------- | ----------- |
| `id` | `string` | primary key |
| `user_id` | any | |
| `expires_at` | `Date` | |
| column | type | attributes |
| ------------ | -------- | ---------- |
| `token_hash` | `string` | unique |
| `user_id` | any | |
| `expires_at` | `Date` | |

## Create verification token

The token should be valid for at most few hours.
The token should be valid for at most few hours. The token should be hashed before storage as it essentially is a password. SHA-256 can be used here since the token is long and random, unlike user passwords.

```ts
import { TimeSpan, createDate } from "oslo";
import { sha256 } from "oslo/crypto";
import { encodeHex } from "oslo/encoding";
import { generateId } from "lucia";

async function createPasswordResetToken(userId: string): Promise<string> {
// optionally invalidate all existing tokens
await db.table("password_reset_token").where("user_id", "=", userId).deleteAll();
const tokenId = generateId(40);
const tokenHash = encodeHex(await sha256(new TextEncoder().encode(tokenId)));
await db.table("password_reset_token").insert({
id: tokenId,
token_hash: tokenHash,
user_id: userId,
expires_at: createDate(new TimeSpan(2, "h"))
});
Expand Down Expand Up @@ -68,11 +73,26 @@ Make sure to implement rate limiting based on IP addresses.

## Verify token

Extract the verification token from the URL and validate by checking the expiration date. If the token is valid, invalidate all existing user sessions, update the database, and create a new session.
Make sure to set the `Referrer-Policy` header of the password reset page to `no-referrer` to protect the token from referrer leakage.

```ts
app.get("/reset-password/:token", async () => {
// ...
return new Response(html, {
headers: {
"Referrer-Policy": "no-referrer"
}
});
})
```

Extract the verification token from the URL and validate by checking the expiration date. If the token is valid, invalidate all existing user sessions, update the database, and create a new session. Make sure to set the `Referrer-Policy` header here as well.

```ts
import { isWithinExpirationDate } from "oslo";
import { Argon2id } from "oslo/password";
import { sha256 } from "oslo/crypto";
import { encodeHex } from "oslo/encoding";

app.post("/reset-password/:token", async () => {
let password = formData.get("password");
Expand All @@ -86,12 +106,14 @@ app.post("/reset-password/:token", async () => {

// ...

await db.beginTransaction();
const token = await db.table("password_reset_token").where("id", "=", verificationToken).get();
const tokenHash = encodeHex(await sha256(new TextEncoder().encode(verificationToken)));
const token = await db
.table("password_reset_token")
.where("token_hash", "=", tokenHash)
.get();
if (token) {
await db.table("password_reset_token").where("id", "=", verificationToken).delete();
await db.table("password_reset_token").where("token_hash", "=", tokenHash).delete();
}
await db.commit();

if (!token || !isWithinExpirationDate(token.expires_at)) {
return new Response(null, {
Expand All @@ -111,8 +133,11 @@ app.post("/reset-password/:token", async () => {
status: 302,
headers: {
Location: "/",
"Set-Cookie": sessionCookie.serialize()
"Set-Cookie": sessionCookie.serialize(),
"Referrer-Policy": "no-referrer"
}
});
});
```


4 changes: 3 additions & 1 deletion docs/pages/guides/oauth/account-linking.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ In general, you'd want to link accounts with the same email. Keep in mind that t
```ts
import { generateId } from "lucia";

const tokens = await github.validateAuthorizationCode(code);
const tokens = await github.validateAuthorizationCode(code, {
scopes: ["user:email"]
});
const userResponse = await fetch("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${tokens.accessToken}`
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/guides/oauth/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ For a step-by-step, framework-specific tutorial, see the [GitHub OAuth](/tutoria
- [PKCE](/guides/oauth/pkce)
- [Account linking](/guides/oauth/account-linking)
- [Custom OAuth providers](/guides/oauth/custom-providers)

We recommend reading through the [OAuth guide](https://thecopenhagenbook.com/oauth) in the Copenhagen Book.
2 changes: 2 additions & 0 deletions docs/pages/guides/passkeys.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ title: "Passkeys"

# Passkeys

Also see the [passkeys guide](https://thecopenhagenbook.com/passkeys) in the Copenhagen Book.

_Work in progress_

0 comments on commit 64df574

Please sign in to comment.