Skip to content

Commit

Permalink
Remove oslo/password from docs (#1554)
Browse files Browse the repository at this point in the history
  • Loading branch information
pilcrowonpaper authored Apr 27, 2024
1 parent 56ed929 commit 82773e5
Show file tree
Hide file tree
Showing 19 changed files with 218 additions and 258 deletions.
20 changes: 2 additions & 18 deletions docs/pages/getting-started/astro.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,10 @@ title: "Getting started in Astro"

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
```

## Update Vite

If you've installed `oslo`, add `oslo` to `vite.optimizeDeps.exclude`.

```ts
// astro.config.mjs
export default defineConfig({
// ...
vite: {
optimizeDeps: {
exclude: ["oslo"]
}
}
});
npm install lucia
```

## Initialize Lucia
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/getting-started/express.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ title: "Getting started in Express"

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
npm install lucia
```

## Initialize Lucia
Expand Down
32 changes: 2 additions & 30 deletions docs/pages/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ A framework-specific guide is also available for:

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
npm install lucia
```

## Initialize Lucia
Expand Down Expand Up @@ -62,34 +62,6 @@ globalThis.crypto = webcrypto as Crypto;
node --experimental-web-crypto index.js
```

## Update bundler configuration

This is only required if you're using `oslo/password`.

### Vite

This is not required if you're Nuxt, SolidStart, or SvelteKit.

```ts
import { defineConfig } from "vite";

export default defineConfig({
// ...
optimizeDeps: {
exclude: ["oslo"]
}
});
```

### Webpack

```ts
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.
26 changes: 2 additions & 24 deletions docs/pages/getting-started/nextjs-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ title: "Getting started in Next.js App router"

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides in the docs use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
npm install lucia
```

## Initialize Lucia
Expand Down Expand Up @@ -56,28 +56,6 @@ globalThis.crypto = webcrypto as Crypto;
node --experimental-web-crypto index.js
```

## Update configuration

If you're planning to use `oslo/password` for hashing passwords, mark its dependencies as external to prevent it from getting bundled.

```ts
// next.config.ts
const nextConfig = {
webpack: (config) => {
config.externals.push("@node-rs/argon2", "@node-rs/bcrypt");
return config;
}
};
```

In addition, if you're deploying to Vercel, you may need to manually install its dependencies.

```
npm install @node-rs/argon2 @node-rs/bcrypt
```

Currently, `oslo/password` cannot be used with Turbopack.

## Next steps

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).
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/getting-started/nextjs-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ title: "Getting started in Next.js Pages router"

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
npm install lucia
```

## Initialize Lucia
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/getting-started/nuxt.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ title: "Getting started in Nuxt"

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
npm install lucia
```

## Initialize Lucia
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/getting-started/solidstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ title: "Getting started in SolidStart"

## Installation

Install Lucia using your package manager of your choice. While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).
Install Lucia using your package manager of your choice.

```
npm install lucia oslo
npm install lucia
```

## Initialize Lucia
Expand Down
8 changes: 0 additions & 8 deletions docs/pages/getting-started/sveltekit.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ Install Lucia using your package manager of your choice.
npm install -D lucia
```

While not strictly necessary, we recommend installing [Oslo](https://oslo.js.org), which Lucia is built on, for various auth utilities (which a lot of the guides use).

If you use `@sveltejs/adapter-node`, make sure to install `oslo` as a `dependency`, not as `devDependency` to prevent Rollup from bundling `oslo`. See the [SvelteKit documentation](https://kit.svelte.dev/docs/adapter-node#deploying) for details.

```
npm install oslo
```

## Initialize Lucia

Import `Lucia` and initialize it with your adapter. Refer to the [Database](/database) page to learn how to set up your database and initialize the adapter. Make sure to configure the `sessionCookie` option and register your `Lucia` instance type
Expand Down
48 changes: 31 additions & 17 deletions docs/pages/guides/email-and-password/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ This page covers how to implement a password-based auth with Lucia. If you're lo

## Update database

Add a unique `email` and `hashed_password` column to the user table.
Add a unique `email` and `password_hash` column to the user table.

| column | type | attributes |
| ----------------- | -------- | ---------- |
| `email` | `string` | unique |
| `hashed_password` | `string` | |
| column | type | attributes |
| --------------- | -------- | ---------- |
| `email` | `string` | unique |
| `password_hash` | `string` | |

Declare the type with `DatabaseUserAttributes` and add the attributes to the user object using the `getUserAttributes()` configuration.

Expand All @@ -29,7 +29,7 @@ export const lucia = new Lucia(adapter, {
},
getUserAttributes: (attributes) => {
return {
// we don't need to expose the hashed password!
// we don't need to expose the password hash!
email: attributes.email
};
}
Expand Down Expand Up @@ -62,7 +62,7 @@ Create a `/signup` route. This will accept POST requests with an email and passw
```ts
import { lucia } from "./auth.js";
import { generateIdFromEntropySize } from "lucia";
import { Argon2id } from "oslo/password";
import { hash } from "@node-rs/argon2";

app.post("/signup", async (request: Request) => {
const formData = await request.formData();
Expand All @@ -79,14 +79,20 @@ app.post("/signup", async (request: Request) => {
});
}

const hashedPassword = await new Argon2id().hash(password);
const passwordHash = await hash(password, {
// recommended minimum parameters
memorySize: 19456,
iterations: 2,
tagLength: 32,
parallelism: 1
});
const userId = generateIdFromEntropySize(10); // 16 characters long

try {
await db.table("user").insert({
id: userId,
email,
hashed_password: hashedPassword
password_hash: passwordHash
});

const session = await lucia.createSession(userId, {});
Expand All @@ -109,16 +115,19 @@ app.post("/signup", async (request: Request) => {

### Hashing passwords

`oslo/password` currently provides [`Argon2id`](https://oslo.js.org/reference/password/Argon2id), [`Scrypt`](https://oslo.js.org/reference/password/Scrypt), and [`Bcrypt`](https://oslo.js.org/reference/password/Bcrypt). These rely on the fastest available libraries but only work in Node.js. Passwords are salted and hashed using settings recommended by OWASP.
Argon2id should be your first choice for hashing passwords, followed by Scrypt and Bcrypt. Hashing is by definition computationally expensive so you should use the most performant option for your runtime.

```ts
import { Argon2id, Scrypt, Bcrypt } from "oslo/password";
```
- For Node.js we recommend using [`@node-rs/argon2`](https://github.com/napi-rs/node-rs).
- For Bun, we recommend using [`Bun.password`](https://bun.sh/docs/api/hashing).
- Use Deno-specific packages for Deno.
- For other runtimes (e.g. Cloudflare Workers), your choice is very limited. [`@noble/hashes`](https://github.com/paulmillr/noble-hashes) provides pure-js implementations of various hashing algorithms, but because it's written in JS, you may hit into CPU limitations of your service. If possible, avoid these runtimes when you need to hash passwords.

For Bun, we recommend using [`Bun.password`](https://bun.sh/docs/api/hashing), which also uses Argon2id by default. For other runtimes, Lucia provides a pure-JS implementation of Scrypt with [`Scrypt`](/reference/main/Scrypt) that works in any environment. However, we do not recommend this for Node.js as it can be 2~3 times slower than the Node-only version. If you're migrating from Lucia v2, you should use [`LegacyScrypt`](/reference/main/LegacyScrypt).
Make sure to check the [recommended minimum parameters for your hashing algorithm](https://thecopenhagenbook.com/password-authentication#password-storage).

If you're migrating from Lucia v2, you should use [`LegacyScrypt`](/reference/main/LegacyScrypt).

```ts
import { Scrypt, LegacyScrypt } from "lucia";
import { LegacyScrypt } from "lucia";
```

## Sign in user
Expand All @@ -127,7 +136,7 @@ Create a `/login` route. This will accept POST requests with an email and passwo

```ts
import { lucia } from "./auth.js";
import { Argon2id } from "oslo/password";
import { verify } from "@node-rs/argon2";

app.post("/login", async (request: Request) => {
const formData = await request.formData();
Expand Down Expand Up @@ -162,7 +171,12 @@ app.post("/login", async (request: Request) => {
});
}

const validPassword = await new Argon2id().verify(user.hashed_password, password);
const validPassword = await verify(user.password_hash, password, {
memorySize: 19456,
iterations: 2,
tagLength: 32,
parallelism: 1
});
if (!validPassword) {
return new Response("Invalid email or password", {
status: 400
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ app.post("/signup", async () => {
await db.table("user").insert({
id: userId,
email,
hashed_password: hashedPassword,
password_hash: passwordHash,
email_verified: false
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ app.post("/signup", async () => {
await db.table("user").insert({
id: userId,
email,
hashed_password: hashedPassword,
password_hash: passwordHash,
email_verified: false
});

Expand Down
8 changes: 8 additions & 0 deletions docs/pages/guides/email-and-password/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ title: "Email and password"

Email-based auth requires a lot of components so be prepared to do some work! For a step-by-step, framework-specific tutorial to learn the basics of password-based auth and Lucia, see the [Username and password](/tutorials/username-and-password) tutorial.

This guide uses [Oslo](https://oslo.js.org), a library that provides various auth-related utilities. This is also used by Lucia internally.

```
npm i oslo
```

˝

- [Password basics](/guides/email-and-password/basics)
- Email verification
- [Email verification codes](/guides/email-and-password/email-verification-codes) (preferred)
Expand Down
12 changes: 9 additions & 3 deletions docs/pages/guides/email-and-password/password-reset.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Extract the verification token from the URL and validate by checking the expirat

```ts
import { isWithinExpirationDate } from "oslo";
import { Argon2id } from "oslo/password";
import { hash } from "@node-rs/argon2";
import { sha256 } from "oslo/crypto";
import { encodeHex } from "oslo/encoding";

Expand Down Expand Up @@ -117,9 +117,15 @@ app.post("/reset-password/:token", async () => {
}

await lucia.invalidateUserSessions(token.user_id);
const hashedPassword = await new Argon2id().hash(password);
const passwordHash = await hash(password, {
// recommended minimum parameters
memorySize: 19456,
iterations: 2,
tagLength: 32,
parallelism: 1
});
await db.table("user").where("id", "=", token.user_id).update({
hashed_password: hashedPassword
password_hash: passwordHash
});

const session = await lucia.createSession(token.user_id, {});
Expand Down
Loading

0 comments on commit 82773e5

Please sign in to comment.