diff --git a/docs/src/content/docs/oauth/notion.mdx b/docs/src/content/docs/oauth/notion.mdx new file mode 100644 index 00000000..e21653b5 --- /dev/null +++ b/docs/src/content/docs/oauth/notion.mdx @@ -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) + +--- + + + + + +## 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. + + + + + +## Notion Aura Auth + +### Installation + +install the package using a package manager like `npm`, `pnpm` or `yarn` + +```npm +npm install @aura-stack/auth +``` + + + + + +### 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" +``` + + + 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. + + + + + + +### 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 +``` + + + + + +### 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 +``` + + + 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. + + + + + + +--- + +## 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) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index f19bedaf..0668e8f6 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -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) diff --git a/packages/core/src/oauth/index.ts b/packages/core/src/oauth/index.ts index f88d645d..5ec31f19 100644 --- a/packages/core/src/oauth/index.ts +++ b/packages/core/src/oauth/index.ts @@ -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" @@ -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, @@ -44,6 +46,7 @@ export const builtInOAuthProviders = { mailchimp, pinterest, twitch, + notion, } as const /** diff --git a/packages/core/src/oauth/notion.ts b/packages/core/src/oauth/notion.ts new file mode 100644 index 00000000..dfff432a --- /dev/null +++ b/packages/core/src/oauth/notion.ts @@ -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 => { + 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 +}