Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions docs/src/content/docs/oauth/notion.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
title: Notion Authorization Provider
description: Add Notion authorization provider to Aura Auth to authenticate and authorize
---

## Notion

Set up `Notion` authorization provider to the authentication instance to Aura Auth.

---

## What you'll learn

Through this quick start guide you are going to learn and understand the basics and how to set up `Notion` provider to Aura Auth.

- [Notion OAuth App](#notion-oauth-app)
- [Creating an OAuth App](#creating-an-oauth-app)
- [Notion Aura Auth](#notion-aura-auth)
- [Installation](#installation)
- [Environment setup](#environment-setup)
- [Configure the provider](#configure-the-provider)
- [Get HTTP handlers](#get-http-handlers)
- [Resources](#resources)

---

<Steps>

<Step>

## Notion OAuth App

### Creating an OAuth app

The first step is create and register a [`Notion Integration`](https://www.notion.so/profile/integrations/public) to grant to have access to the user's accessible resources like `Retrieve the Bot User` (Used by Aura Auth), `Pages`, `Comments`, `Databases`, etc. For more detailed information read [Get Started Authorization](https://developers.notion.com/guides/get-started/authorization), [Notion Integrations](https://www.notion.so/profile/integrations/public) and [Get Self User](https://developers.notion.com/reference/get-self).

Registering an Notion OAuth app includes:

- `Integration name`: The application name showed when the user tries to grant to the app.
- `Associated workspace`: The workspace that the app belongs to, it can be changed later.
- `Company name`: The company name showed when the user tries to grant to the app.
- `Website`: The URL of the website, it can be changed later.
- `Tagline`: The tagline of the app, it can be changed later.
- `Privacy Policy URL`: The URL of the privacy policy, it can be changed later.
- `Terms of Use URL`: The URL of the terms of use, it can be changed later.
- `Email`: The email of the developer, it can be changed later.
- `Authorization URL`: The URL which the Notion will redirect, it should end in `/auth/callback/notion` for local and production environment.
- Local environment: `http://localhost:3000/auth/callback/notion`
- Production environment: production set the URL of the application.

</Step>

<Step>

## Notion Aura Auth

### Installation

install the package using a package manager like `npm`, `pnpm` or `yarn`

```npm
npm install @aura-stack/auth
```

</Step>

<Step>

### Environment setup

Now, it's time to create and consume the Notion credentials required and used by Aura Auth, it include the `client Id` and `client Secret` and write them into a `.env` file.

Additionally set the `secret` used by Aura Auth to sign and encrypt the user's session.

```bash title=".env" lineNumbers
# Notion Credentials
AURA_AUTH_NOTION_CLIENT_ID="notion_client_id"
AURA_AUTH_NOTION_CLIENT_SECRET="notion_client_secret"

# Aura Secret
AURA_AUTH_SECRET="32-bytes-secret"
```

<Callout type="warning">
The `AURA_AUTH_SECRET` will recommended to be random and high antropy key to avoid attackers decifer the secret used by the Aura
Auth application.
</Callout>

</Step>

<Step>

### Configure the provider

Set the `oauth` option of the `createAuth` instance. You can use the provider name as a string to use default settings, or use the `notion` factory function to customize the configuration.

#### Default configuration

```ts title="@/auth" lineNumbers
import { createAuth } from "@aura-stack/auth"

export const auth = createAuth({
oauth: ["notion"],
})

export const { handlers } = auth
```

#### Custom configuration

```ts title="@/auth" lineNumbers
import { createAuth } from "@aura-stack/auth"
import { notion } from "@aura-stack/auth/oauth/notion"

export const auth = createAuth({
oauth: [
notion({
scope: "read:user user:email repo",
}),
],
})

export const { handlers } = auth
```

</Step>

<Step>

### Get HTTP Handlers

Use the HTTP handlers to consume the authentication logic and flow the Aura Auth library to be integrated into routers and frameworks.

```ts title="backend.ts" lineNumbers
import { handlers } from "@/auth"

export const { GET, POST } = handlers
```

<Callout>
The returned handlers include pre-built routes used in OAuth flows (`/signIn/:oauth`, `/callback/:oauth`, `/session`, `/signOut`
and `/csrfToken`). You can mount them in Express, Hono, Next.js, or any runtime that supports native Request and Response APIs.
</Callout>

</Step>

</Steps>

---

## Resources

- [RFC - The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)
- [Notion - Developer Documentation](https://developers.notion.com/)
- [Notion - Authorization](https://developers.notion.com/docs/authorization)
- [Notion - Authentication](https://developers.notion.com/reference/authentication)
- [Notion - Retrieve your token's bot user](https://developers.notion.com/reference/get-self)
2 changes: 2 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Added

- Added the `Notion` OAuth provider to the supported integrations in Aura Auth. [#49](https://github.com/aura-stack-ts/auth/pull/49)

- Added the `Twitch` OAuth provider to the supported integrations in Aura Auth. [#47](https://github.com/aura-stack-ts/auth/pull/47)

- Added support for loading authentication configuration from environment variables, including `DEBUG`, `LOG_LEVEL`, `TRUSTED_ORIGINS`, and `TRUSTED_PROXY_HEADERS`. Also updated automatic environment variable loading patterns. [#108](https://github.com/aura-stack-ts/auth/pull/108)
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/oauth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { strava } from "./strava.ts"
import { mailchimp } from "./mailchimp.ts"
import { pinterest } from "./pinterest.ts"
import { twitch } from "./twitch.ts"
import { notion } from "./notion.ts"
import { OAuthEnvSchema, OAuthProviderCredentialsSchema } from "@/schemas.ts"
import { AuthInternalError } from "@/errors.ts"
import { formatZodError } from "@/utils.ts"
Expand All @@ -31,6 +32,7 @@ export * from "./strava.ts"
export * from "./mailchimp.ts"
export * from "./pinterest.ts"
export * from "./twitch.ts"
export * from "./notion.ts"

export const builtInOAuthProviders = {
github,
Expand All @@ -44,6 +46,7 @@ export const builtInOAuthProviders = {
mailchimp,
pinterest,
twitch,
notion,
} as const

/**
Expand Down
81 changes: 81 additions & 0 deletions packages/core/src/oauth/notion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createBasicAuthHeader } from "@/utils.ts"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

export interface Person {
email: string
}

export interface User {
object: "user"
id: string
name: string
avatar_url: string | null
type: "person"
person: Person
}

export interface Owner {
type: "user"
user: User
}

export interface Bot {
owner: Owner
}

/**
* @see [Notion - Retrieve your token's bot user](https://developers.notion.com/reference/get-self)
*/
export interface NotionProfile {
object: "user"
id: string
name: string
avatar_url: string | null
type: "bot"
bot: Bot
}

/**
* @see [Notion - Developer Documentation](https://developers.notion.com/)
* @see [Notion - Authorization](https://developers.notion.com/docs/authorization)
* @see [Notion - Authentication](https://developers.notion.com/reference/authentication)
* @see [Notion - Retrieve your token's bot user](https://developers.notion.com/reference/get-self)
*/
export const notion = (options?: Partial<OAuthProviderCredentials<NotionProfile>>): OAuthProviderCredentials<NotionProfile> => {
return {
id: "notion",
name: "Notion",
authorize: {
url: "https://api.notion.com/v1/oauth/authorize",
params: {
owner: "user",
scope: "user:read",
responseType: "code",
},
},
accessToken: {
url: "https://api.notion.com/v1/oauth/token",
headers: {
Authorization: createBasicAuthHeader(
options?.clientId ?? "NOTION_CLIENT_ID",
options?.clientSecret ?? "NOTION_CLIENT_SECRET"
),
},
},
userInfo: {
url: "https://api.notion.com/v1/users/me",
headers: {
"Notion-Version": "2022-06-28",
},
},
profile(profile) {
return {
sub: profile.id,
name: profile.name,
image: profile.avatar_url ?? "",
email: profile?.bot?.owner?.user?.person?.email,
}
},
...options,
} as OAuthProviderCredentials<NotionProfile>
}