Skip to content

Commit

Permalink
Unify OAuth API (#993)
Browse files Browse the repository at this point in the history
  • Loading branch information
pilcrowonpaper authored Aug 22, 2023
1 parent e5cbf80 commit a03e7d2
Show file tree
Hide file tree
Showing 67 changed files with 2,904 additions and 2,191 deletions.
6 changes: 6 additions & 0 deletions .auri/$50cmkct.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "minor" # "major", "minor", "patch"
---

Experimental API `createOAuth2AuthorizationUrl()`, `createOAuth2AuthorizationUrlWithPKCE()`, `validateOAuth2AuthorizationCode()`, and `decodeIdToken()` are now stable
6 changes: 6 additions & 0 deletions .auri/$50cmkct2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "minor" # "major", "minor", "patch"
---

Update `createOAuth2AuthorizationUrlWithPKCE()` return type
6 changes: 6 additions & 0 deletions .auri/$50cmkcw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "major" # "major", "minor", "patch"
---

Remove `generateState()` export
6 changes: 6 additions & 0 deletions .auri/$50cmkcw4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "major" # "major", "minor", "patch"
---

Replace `OAuthProvider` with `OAuth2ProviderAuth` and `OAuth2ProviderAuthWithPKCE`
6 changes: 6 additions & 0 deletions .auri/$50cmkcwp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "major" # "major", "minor", "patch"
---

Replace `GithubProvider` with `GithubAuth` etc
7 changes: 7 additions & 0 deletions .auri/$9dl3rkfo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
package: "@lucia-auth/oauth" # package name
type: "minor" # "major", "minor", "patch"
pull: "1005"
---

Add Azure Active Directory provider
6 changes: 6 additions & 0 deletions .auri/$znnf49ht.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "minor" # "major", "minor", "patch"
---

Remove `options.searchParams` and `options.state` from `createOAuth2AuthorizationUrl()` and `createOAuth2AuthorizationUrlWithPKCE()` params
6 changes: 6 additions & 0 deletions .auri/$znnf49htd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
package: "@lucia-auth/oauth" # package name
type: "major" # "major", "minor", "patch"
---

Update `auth0()`, `google()`, `patreon()`, `reddit()`, `spotify()`, `twitch()` params
2 changes: 1 addition & 1 deletion documentation/content/guidebook/oauth-account-linking.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const user = await getUser();

Instead of creating a new user, we can check if a user with the email already exists, and if so, link the authentication method to that user by creating a new key.

It's important to note `existingUser` is defined if a user linked to the provider's user id (e.g. Github user id) exists. It is _not_ based on the email. As such, you will have to query the user table to find if a user with the email already exists. If it does, use [`ProviderUserAuth.createKey()`]() to link the method to the user. You can use [`transformDatabaseUser()`]() to get Lucia's `User` object from the database result.
It's important to note `existingUser` is defined if a user linked to the provider's user id (e.g. Github user id) exists. It is _not_ based on the email. As such, you will have to query the user table to find if a user with the email already exists. If it does, use [`ProviderUserAuth.createKey()`](/reference/oauth/interfaces/provideruserauth#createkey) to link the method to the user. You can use [`transformDatabaseUser()`](/reference/lucia/interfaces/auth#transformdatabaseuser) to get Lucia's `User` object from the database result.

**It's crucial to ensure that the email has been verified.**

Expand Down
141 changes: 0 additions & 141 deletions documentation/content/oauth/basics/built-in-providers.md

This file was deleted.

78 changes: 78 additions & 0 deletions documentation/content/oauth/basics/handle-users.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: "Handle users with Lucia"
description: "Learn how to use the built-in OAuth 2.0 providers"
---

After authenticating the user with OAuth, you can get an existing or create a new Lucia user using [`ProviderUserAuth`](/reference/oauth/interfaces/provideruserauth). If you're using one of the built in providers, [`OAuth2ProviderAuth.validateCallback()`](reference/oauth/interfaces/oauth2providerauth#validatecallback) and [`OAuth2ProviderAuthWithPKCE.validateCallback()`](reference/oauth/interfaces/oauth2providerauthwithpkce#validatecallback) will return a provider-extended instance of it.

```ts
import { github } from "@lucia-auth/oauth/providers";

const githubAuth = github();
const githubUserAuth = githubAuth.validateCallback();
```

Alternatively, if you're using one of the OAuth helpers, you can use [`providerUserAuth()`](/reference/oauth/modules/main#provideruserauth) to manually create a new instance of it. It takes your Lucia `Auth` instance, the provider id (e.g. `"github"`), and the provider user id (e.g. Github user id).

```ts
const githubUserAuth = providerUserAuth(auth, "github", githubUserId);
```

## Basic usage

[`ProviderUserAuth.getExistingUser()`](/reference/oauth/interfaces/provideruserauth/#getexistinguser) will return a `User` if a Lucia user already exists for the authenticated provider account. This is based on the provider user id (e.g. Github user id) and not shared identifiers like email.

If not, you can create a new Lucia user linked to the provider with [`ProviderUserAuth.createUser()`](/reference/oauth/interfaces/provideruserauth#createuser). You can get the provider user data with `githubUser` for Github, etc.

```ts
const getUser = async () => {
const existingUser = await githubUserAuth.getExistingUser();
if (existingUser) return existingUser;
// create a new user if the user does not exist
return await githubUserAuth.createUser({
attributes: {
githubUsername: githubUser.login
}
});
};
const user = await getUser();

// login user
const session = await auth.createSession({
userId: user.userId,
attributes: {}
});
const authRequest = auth.handleRequest();
authRequest.setSession(session); // store session cookie
```

## Add a new key to an existing user

Alternatively, you may want to add a new authentication method to an existing user. Calling [`ProviderUserAuth.createKey()`](/reference/oauth/interfaces/provideruserauth#createkey) will create a new key linked to the provided user id.

```ts
const existingUser = githubUserAuth.getExistingUser();
if (existingUser) {
await createKey(currentUser.userId);
}
```

See [OAuth account linking](/guidebook/oauth-account-linking) guide for details.

## Extension

If you're using one of the built in providers, `OAuth2ProviderAuth.validateCallback()` and `OAuth2ProviderAuthWithPKCE.validateCallback()` will return a provider-extended instance of `ProviderUserAuth`. This means in addition to the methods of `ProviderUserAuth`, it includes a few other properties and methods. While this isn't strictly standardized, all providers include the provider user (e.g. github user) and an access token (refresh token if available).

### Get provider user

```ts
const githubUserAuth = await githubAuth.validateCallback(code);
const githubUsername = githubUserAuth.githubUser.login;
```

### Get API tokens

```ts
const githubUserAuth = await githubAuth.validateCallback(code);
const githubAccessToken = githubUserAuth.githubTokens.accessToken;
```
Loading

0 comments on commit a03e7d2

Please sign in to comment.