diff --git a/docs/.idea/docs.iml b/docs/.idea/docs.iml index ddbae112..a58c271d 100644 --- a/docs/.idea/docs.iml +++ b/docs/.idea/docs.iml @@ -6,6 +6,7 @@ + diff --git a/docs/docs/adapters/express.md b/docs/docs/adapters/express.md index 8798318c..3a9e6eea 100644 --- a/docs/docs/adapters/express.md +++ b/docs/docs/adapters/express.md @@ -1,31 +1,47 @@ # Express -[Express](https://expressjs.com/) +:::info -Adapts the [Express.Request](https://expressjs.com/en/api.html#req) and [Express.Response](https://expressjs.com/en/api.html#res) for use with `@jmondi/oauth2-server`. +Available in >2.0.0 -```typescript -import { - requestFromExpress, - handleExpressResponse, - handleExpressError, -} from "@jmondi/oauth2-server/express"; -``` +::: -```typescript -requestFromExpress(req: Express.Request): OAuthRequest; -``` +This adapter provides utility functions to convert between Express [Request](https://expressjs.com/en/api.html#req) and [Response](https://expressjs.com/en/api.html#res) objects and the `OAuthRequest`/`OAuthResponse` objects used by this package. -Helper function to return an OAuthRequest from an `Express.Request`. +## Functions -```typescript -handleExpressResponse(expressResponse: Express.Response, oauthResponse: OAuthResponse): void; +```ts +requestFromExpress(req: Express.Request): OAuthRequest ``` -Helper function that handles the express response after authorization. +```ts +handleExpressResponse(expressResponse: Express.Response, oauthResponse: OAuthResponse): void +``` -```typescript -handleExpressError(res: Express.Response, e: unknown | OAuthException): void; +```ts +handleExpressError(res: Express.Response, e: unknown | OAuthException): void ``` -Helper function that handles the express response if an error was thrown. +## Example + +```ts +import { requestFromExpress, handleExpressResponse, handleExpressError } from "@jmondi/oauth2-server/express"; +import express from 'express'; + +const app = express(); + +// ... + +app.post('/oauth2/token', async (req: express.Request, res: express.Response) => { + const authorizationServer = req.app.get('authorization_server'); + + try { + const oauthResponse = await authorizationServer + .respondToAccessTokenRequest(requestFromExpress(req)); + + handleExpressResponse(res, oauthResponse); + } catch (e) { + handleExpressError(res, e); + } +}); +``` diff --git a/docs/docs/adapters/fastify.md b/docs/docs/adapters/fastify.md index bdeba981..de4c34ba 100644 --- a/docs/docs/adapters/fastify.md +++ b/docs/docs/adapters/fastify.md @@ -1,31 +1,48 @@ # Fastify -Adapts the [Fastify.Request](https://fastify.dev/docs/latest/Reference/Request/) and [Fastify.Reply](https://fastify.dev/docs/latest/Reference/Reply/) for use with `@jmondi/oauth2-server`. - -```typescript -import { - requestFromFastify, - handleFastifyReply, - handleFastifyError, -} from "@jmondi/oauth2-server/fastify"; -``` +:::info -The following functions are imported directly from the adapter instead of the root package. +Available in >2.0.0 + +::: -```typescript -requestFromFastify(req: FastifyRequest): OAuthRequest; -``` -Helper function to return an OAuthRequest from an `FastifyRequest`. +This adapter provides utility functions to convert between Fastify [Request](https://fastify.dev/docs/latest/Reference/Request/) and [Reply](https://fastify.dev/docs/latest/Reference/Reply/) objects and the `OAuthRequest`/`OAuthResponse` objects used by this package. -```typescript -handleFastifyReply(fastifyReply: FasitfyReply, oauthResponse: OAuthResponse): void; +## Functions + +```ts +requestFromFastify(req: FastifyRequest): OAuthRequest ``` -Helper function that handles the express response after authorization. +```ts +handleFastifyReply(fastifyReply: FastifyReply, oauthResponse: OAuthResponse): void +``` -```typescript -handleFastifyError(reply: FasitfyReply, e: unknown | OAuthException): void; +```ts +handleFastifyError(reply: FastifyReply, e: unknown | OAuthException): void ``` -Helper function that handles the express response if an error was thrown. +## Example + +```ts +import { requestFromFastify, handleFastifyReply, handleFastifyError } from "@jmondi/oauth2-server/fastify"; +import fastify from 'fastify' + +const app = fastify() + +// ... + +app.post('/oauth2/token', async (request: fastify.Request, reply: fastify.Reply) => { + const authorizationServer = request.server.authorizationServer; + + try { + const oauthResponse = await authorizationServer + .respondToAccessTokenRequest(requestFromFastify(request)); + + handleFastifyReply(reply, oauthResponse); + } catch (e) { + handleFastifyError(reply, e); + } +}); +``` diff --git a/docs/docs/adapters/index.md b/docs/docs/adapters/index.md index 586b9be1..341d396f 100644 --- a/docs/docs/adapters/index.md +++ b/docs/docs/adapters/index.md @@ -9,4 +9,4 @@ Adapters are a set of helper functions to provide framework specific integration - [Express](./express) - If you're using Express, you can use the `@jmondi/oauth2-server/express` adapter. - [Fastify](./fastify) - If you're using Fastify, you can use the `@jmondi/oauth2-server/fastify` adapter. -- [VanillaJS](./vanilla) - If you're using Honojs, Sveltekit or Nextjs, you can use the `@jmondi/oauth2-server/vanilla` adapter. +- [VanillaJS](./vanilla) - Adapts the Fetch [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) so you can use Honojs, Sveltekit, Nextjs or whatever tool your using that uses the native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) `@jmondi/oauth2-server/vanilla` adapter. diff --git a/docs/docs/adapters/vanilla.md b/docs/docs/adapters/vanilla.md index 4f6b9642..d4f83e16 100644 --- a/docs/docs/adapters/vanilla.md +++ b/docs/docs/adapters/vanilla.md @@ -10,32 +10,43 @@ Available in >3.4.0 ::: -Adapts the Fetch [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) for use with `@jmondi/oauth2-server`. - -```typescript -import { - requestFromVanilla, - handleVanillaReply, - handleVanillaError, -} from "@jmondi/oauth2-server/vanilla"; -``` +This adapter provides utility functions to convert between vanilla JavaScript [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) objects and the `OAuthRequest`/`OAuthResponse` objects used by the this package. -The following functions are imported directly from the adapter instead of the root package. +## Functions -```typescript -requestFromVanilla(req: Request): OAuthRequest; +```ts +responseFromVanilla(res: Response): OAuthResponse ``` -Helper function to return an OAuthRequest from an `VanillaRequest`. +```ts +requestFromVanilla(req: Request): OAuthRequest +``` -```typescript -handleVanillaReply(res: Response, oauthResponse: OAuthResponse): void; +```ts +responseToVanilla(oauthResponse: OAuthResponse): Response ``` -Helper function that handles the express response after authorization. +## Example -```typescript -handleVanillaError(res: Response, e: unknown | OAuthException): void; -``` +```ts +import { requestFromVanilla, responseToVanilla } from "@jmondi/oauth2-server/vanilla"; + +import { Hono } from 'hono' +const app = new Hono() + +// ... -Helper function that handles the express response if an error was thrown. +app.post('/oauth2/token', async (c) => { + const authorizationServer = c.get("authorization_server"); + + const oauthResponse = await authorizationServer + .respondToAccessTokenRequest(requestFromVanilla(request)) + .catch(e => { + error(400, e.message); + }); + + return responseToVanilla(oauthResponse); +}); + +export default app +``` diff --git a/docs/docs/authorization_server/configuration.mdx b/docs/docs/authorization_server/configuration.mdx index d25de70c..2d407a36 100644 --- a/docs/docs/authorization_server/configuration.mdx +++ b/docs/docs/authorization_server/configuration.mdx @@ -28,7 +28,7 @@ type AuthorizationServerOptions = { To configure these options, pass the value in as the last argument: -```typescript +```ts const authorizationServer = new AuthorizationServer( clientRepository, accessTokenRepository, diff --git a/docs/docs/authorization_server/index.mdx b/docs/docs/authorization_server/index.mdx index c7ca91fb..cea105fb 100644 --- a/docs/docs/authorization_server/index.mdx +++ b/docs/docs/authorization_server/index.mdx @@ -10,7 +10,7 @@ The `AuthorizationServer` is a core component of the OAuth 2.0 framework, respon To create an instance of the `AuthorizationServer`, use the following constructor: -```typescript +```ts const authorizationServer = new AuthorizationServer( clientRepository, accessTokenRepository, @@ -32,7 +32,7 @@ Parameters: By default, no grant types are enabled when creating an `AuthorizationServer`. Each grant type must be explicitly enabled using the `enableGrantType` method. This approach allows for fine-grained control over which OAuth 2.0 flows your server supports. -```typescript +```ts authorizationServer.enableGrantType("client_credentials"); authorizationServer.enableGrantType("refresh_token"); authorizationServer.enableGrantType({ @@ -49,7 +49,7 @@ Note that the Authorization Code grant requires additional repositories: `userRe You can enable multiple grant types on the same server: -```typescript +```ts const authorizationServer = new AuthorizationServer( clientRepository, accessTokenRepository, diff --git a/docs/docs/getting_started/endpoints.mdx b/docs/docs/getting_started/endpoints.mdx index e2dbf5ba..5b7a8bb1 100644 --- a/docs/docs/getting_started/endpoints.mdx +++ b/docs/docs/getting_started/endpoints.mdx @@ -8,7 +8,7 @@ sidebar_position: 4 The `/token` endpoint is a back channel endpoint that issues a usable access token. -```typescript +```ts app.post("/token", async (req: Express.Request, res: Express.Response) => { try { const oauthResponse = await authorizationServer.respondToAccessTokenRequest(req); @@ -26,7 +26,7 @@ The `/authorize` endpoint is a front channel endpoint that issues an authorizati The endpoint should redirect the user to login, and then to accept the scopes requested by the application, and only when the user accepts, should it send the user back to the clients redirect uri. -```typescript +```ts import { requestFromExpress } from "@jmondi/oauth2-server/express"; app.get("/authorize", async (req: Express.Request, res: Express.Response) => { @@ -83,7 +83,7 @@ Implementing this endpoint is optional, but recommended. RFC7009 “OAuth 2.0 To The `/token/revoke` endpoint is a back channel endpoint that revokes an existing token. -```typescript +```ts app.post("/token/revoke", async (req: Express.Request, res: Express.Response) => { try { const oauthResponse = await authorizationServer.revoke(req); diff --git a/docs/docs/getting_started/entities.md b/docs/docs/getting_started/entities.md index 3f90d9ae..acb72d55 100644 --- a/docs/docs/getting_started/entities.md +++ b/docs/docs/getting_started/entities.md @@ -16,7 +16,7 @@ The Client Entity represents an application that requests access to protected re ::: -```typescript +```ts interface OAuthClient { id: string; name: string; @@ -50,7 +50,7 @@ type CodeChallengeMethod = "S256" | "plain"; The Token Entity represents access and refresh tokens issued to clients. -```typescript +```ts interface OAuthToken { accessToken: string; accessTokenExpiresAt: Date; @@ -67,7 +67,7 @@ interface OAuthToken { The User Entity represents the resource owner - typically the end-user who authorizes an application to access their account. -```typescript +```ts interface OAuthUser { id: string; [key: string]: any; @@ -80,7 +80,7 @@ Scopes are used to define and limit the extent of access granted to a client app For more information on OAuth 2.0 scopes, visit: https://www.oauth.com/oauth2-servers/scope/ -```typescript +```ts interface OAuthScope { name: string; [key: string]: any; diff --git a/docs/docs/getting_started/index.mdx b/docs/docs/getting_started/index.mdx index 860dcd74..84f413c2 100644 --- a/docs/docs/getting_started/index.mdx +++ b/docs/docs/getting_started/index.mdx @@ -29,15 +29,21 @@ This section provides a high-level overview of setting up the OAuth2 server. 1. Set up the [AuthorizationServer](#the-authorization-server) with desired grant types 1. Implement the [Endpoints](./endpoints) -## Installation +### Installation Choose your preferred package manager to install @jmondi/oauth2-server: -## Basic Setup +### Implement Entities -### The Authorization Server +You are going to need to setup the entities that the OAuth2 server uses to store data. + +### Implement Repositories + +Next you need to implement the repositories that the OAuth2 server uses to interact with the entities. See the [full list of repositories](./repositories.md). + +### Setup the Authorization Server The AuthorizationServer is the core component of the OAuth2 implementation. It requires repositories for managing clients, access tokens, and scopes. Grant types are opt-in and must be explicitly enabled. diff --git a/docs/docs/getting_started/repositories.md b/docs/docs/getting_started/repositories.md index b2d2aa96..d5b533de 100644 --- a/docs/docs/getting_started/repositories.md +++ b/docs/docs/getting_started/repositories.md @@ -8,7 +8,7 @@ sidebar_position: 3 OAuthAuthCodeRepository interface is utilized for managing OAuth authorization codes. It contains methods for retrieving an authorization code entity by its identifier, issuing a new authorization code, persisting an authorization code in the storage, checking if an authorization code has been revoked, and revoking an authorization code. -```typescript +```ts interface OAuthAuthCodeRepository { // Fetch auth code entity from storage by code getByIdentifier(authCodeCode: string): Promise; @@ -37,7 +37,7 @@ interface OAuthAuthCodeRepository { OAuthClientRepository interface is used for managing OAuth clients. It includes methods for fetching a client entity from storage by the client ID and for validating the client using the grant type and client secret. -```typescript +```ts interface OAuthClientRepository { // Fetch client entity from storage by client_id getByIdentifier(clientId: string): Promise; @@ -55,7 +55,7 @@ interface OAuthClientRepository { The OAuthScopeRepository interface handles scope management. It defines methods for finding all scopes by their names and for finalizing the scopes. In the finalization, additional scopes can be added or removed after they've been validated against the client scopes. -```typescript +```ts interface OAuthScopeRepository { // Find all scopes by scope names getAllByIdentifiers(scopeNames: string[]): Promise; @@ -77,7 +77,7 @@ interface OAuthScopeRepository { OAuthTokenRepository interface manages OAuth tokens. It contains methods for issuing a new token, persisting a token in the storage, issuing a refresh token, revoking tokens, and fetching a refresh token entity by the refresh token. -```typescript +```ts interface OAuthTokenRepository { // An async call that should return an OAuthToken that has not been // persisted to storage yet. @@ -114,7 +114,7 @@ interface OAuthTokenRepository { The OAuthUserRepository interface handles user management. It defines methods for fetching a user entity from storage by their credentials and optional grant type and client. This may involve validating the user's credentials. -```typescript +```ts interface OAuthUserRepository { // Fetch user entity from storage by identifier. A provided password may // be used to validate the users credentials. Grant type and client are provided diff --git a/docs/docs/grants/authorization_code.mdx b/docs/docs/grants/authorization_code.mdx index 8098d4c3..1b790275 100644 --- a/docs/docs/grants/authorization_code.mdx +++ b/docs/docs/grants/authorization_code.mdx @@ -130,7 +130,7 @@ Before initializing [Part One](#part-one) of the authorization code flow, the cl We can do this in Node using the native crypto package and a `base64urlencode` function: -```typescript +```ts import crypto from "node:crypto"; const code_verifier = crypto.randomBytes(43).toString("hex"); @@ -144,19 +144,19 @@ Now we need to create a `code_challenge` from our `code_verifier`. For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier. -```typescript +```ts const code_challenge = base64urlencode(crypto.createHash("sha256").update(code_verifier).digest()); ``` Clients that do not have the ability to perform a SHA256 hash are permitted to use the plain `code_verifier` string as the `code_challenge`. -```typescript +```ts const code_challenge = code_verifier; ```
Need a base64urlencode function? - ```typescript + ```ts function base64urlencode(str: string) { return Buffer.from(str) .toString("base64") diff --git a/docs/docs/grants/custom_grant.mdx b/docs/docs/grants/custom_grant.mdx index fe8b9d88..3a1fd9e6 100644 --- a/docs/docs/grants/custom_grant.mdx +++ b/docs/docs/grants/custom_grant.mdx @@ -20,7 +20,7 @@ export class MyCustomGrant extends CustomGrant { Use your custom grant -```typescript +```ts const authorizationServer = new AuthorizationServer( clientRepository, accessTokenRepository, diff --git a/docs/docs/grants/password.mdx b/docs/docs/grants/password.mdx index 3228f329..5620c4fa 100644 --- a/docs/docs/grants/password.mdx +++ b/docs/docs/grants/password.mdx @@ -9,10 +9,6 @@ import TabItem from "@theme/TabItem"; The Password Grant is for first party clients that are able to hold secrets (ie not Browser or Native Mobile Apps) -:::warning -The client_credentials grant should only be used by clients that can hold a secret -::: - ### Flow A complete refresh token request will include the following parameters: @@ -74,14 +70,13 @@ The authorization server will respond with the following response Cache-Control: no-store Pragma: no-cache -{ -token_type: 'Bearer', -expires_in: 3600, -access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1MTJhYjlhNC1jNzg2LTQ4YTYtOGFkNi05NGM1M2E4ZGM2NTEiLCJleHAiOjE2MDE3NjcyOTksIm5iZiI6MTYwMTc2MzY5OSwiaWF0IjoxNjAxNzYzNjk5LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.sX6SWc2Af8jn-izFnrLgNIcNuZz_tRLl2p7M3CzQwKg', -refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIzNTYxNWYyZi0xM2ZhLTQ3MzEtODNhMS05ZTM0NTU2YWIzOTAiLCJhY2Nlc3NfdG9rZW5faWQiOiJuZXcgdG9rZW4iLCJyZWZyZXNoX3Rva2VuX2lkIjoidGhpcy1pcy1teS1zdXBlci1zZWNyZXQtcmVmcmVzaC10b2tlbiIsInNjb3BlIjoiIiwidXNlcl9pZCI6IjUxMmFiOWE0LWM3ODYtNDhhNi04YWQ2LTk0YzUzYThkYzY1MSIsImV4cGlyZV90aW1lIjoxNjAxNzY3Mjk5LCJpYXQiOjE2MDE3NjM2OTh9.SSa7miIdk3bxyzg0f3M9jKBXWjPgD4QEw-AU3SYvBk0', -scope: 'contacts.read contacts.write' -} + { + token_type: 'Bearer', + expires_in: 3600, + access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1MTJhYjlhNC1jNzg2LTQ4YTYtOGFkNi05NGM1M2E4ZGM2NTEiLCJleHAiOjE2MDE3NjcyOTksIm5iZiI6MTYwMTc2MzY5OSwiaWF0IjoxNjAxNzYzNjk5LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.sX6SWc2Af8jn-izFnrLgNIcNuZz_tRLl2p7M3CzQwKg', + refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIzNTYxNWYyZi0xM2ZhLTQ3MzEtODNhMS05ZTM0NTU2YWIzOTAiLCJhY2Nlc3NfdG9rZW5faWQiOiJuZXcgdG9rZW4iLCJyZWZyZXNoX3Rva2VuX2lkIjoidGhpcy1pcy1teS1zdXBlci1zZWNyZXQtcmVmcmVzaC10b2tlbiIsInNjb3BlIjoiIiwidXNlcl9pZCI6IjUxMmFiOWE0LWM3ODYtNDhhNi04YWQ2LTk0YzUzYThkYzY1MSIsImV4cGlyZV90aW1lIjoxNjAxNzY3Mjk5LCJpYXQiOjE2MDE3NjM2OTh9.SSa7miIdk3bxyzg0f3M9jKBXWjPgD4QEw-AU3SYvBk0', + scope: 'contacts.read contacts.write' + } -``` + ```
-``` diff --git a/docs/docs/upgrade_guide.md b/docs/docs/upgrade_guide.md index d7554a54..d2fe8681 100644 --- a/docs/docs/upgrade_guide.md +++ b/docs/docs/upgrade_guide.md @@ -16,7 +16,7 @@ In v2.x, `AuthorizationServer` constructor required all repositories. In v3.x, i **Before (v2.x):** -```typescript +```ts const authorizationServer = new AuthorizationServer( authCodeRepository, clientRepository, @@ -33,7 +33,7 @@ const authorizationServer = new AuthorizationServer( **After (v3.x):** -```typescript +```ts const authorizationServer = new AuthorizationServer( clientRepository, accessTokenRepository, @@ -56,13 +56,13 @@ In v3, `enableGrantType` has been updated for the **"authorization_code"** and * **Before (v2.x):** -```typescript +```ts authorizationServer.enableGrantType("authorization_code"); ``` **After (v3.x):** -```typescript +```ts authorizationServer.enableGrantType({ grant: "authorization_code", userRepository, @@ -76,13 +76,13 @@ authorizationServer.enableGrantType({ **Before (v2.x):** -```typescript +```ts authorizationServer.enableGrantType("password"); ``` **After (v3.x):** -```typescript +```ts authorizationServer.enableGrantType({ grant: "password", userRepository, diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index ee21219b..8da363b8 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -8,7 +8,7 @@ const config: Config = { plugins: [tailwindPlugin], tagline: "Standards-Compliant OAuth 2.0 Server in TypeScript, Utilizing JWT and Proof Key for Code Exchange (PKCE)", - favicon: "img/favicon.ico", + favicon: "favicon.ico", url: "https://tsoauth2server.com", baseUrl: "/", onBrokenLinks: "throw", @@ -18,7 +18,7 @@ const config: Config = { locales: ["en"], }, scripts: [ - { src: "https://plausible.io/js/script.js", defer: true, "data-domain": "tsoauth2server.com" } + { src: "https://plausible.io/js/script.js", defer: true, "data-domain": "tsoauth2server.com" }, ], presets: [ [ @@ -90,9 +90,9 @@ const config: Config = { darkTheme: prismThemes.dracula, }, algolia: { - appId: 'JP2YS2S0EQ', - apiKey: 'bf2bc45ac2821dba462ee887527c1816', - indexName: 'tsoauth2server', + appId: "JP2YS2S0EQ", + apiKey: "bf2bc45ac2821dba462ee887527c1816", + indexName: "tsoauth2server", }, } satisfies Preset.ThemeConfig, }; diff --git a/docs/package.json b/docs/package.json index dc784120..73b18be3 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "start": "docusaurus start", + "start": "docusaurus start --port 8000", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", diff --git a/docs/src/components/MarkdownWrapper.tsx b/docs/src/components/MarkdownWrapper.tsx index 282998f4..540d5478 100644 --- a/docs/src/components/MarkdownWrapper.tsx +++ b/docs/src/components/MarkdownWrapper.tsx @@ -1,15 +1,15 @@ -import React from "react"; +import { ReactNode } from "react"; interface MDXWrapperProps { - children: React.ReactNode; + children: ReactNode; } -const MDXWrapper: React.FC = ({ children }) => { +function MDXWrapper({ children }) { return ( -
+
{children}
); -}; +} export default MDXWrapper; diff --git a/docs/src/pages/_logos.tsx b/docs/src/pages/_logos.tsx new file mode 100644 index 00000000..ef8633e6 --- /dev/null +++ b/docs/src/pages/_logos.tsx @@ -0,0 +1,76 @@ +export function GithubLogo() { + return ( + + + + ); +} + +export function FastifyLogo() { + return ( + + + + ); +} + +export function ExpressLogo() { + return ( + + + + ); +} + +export function TSLogo() { + return ( + + + + ); +} + +export function NPMLogo() { + return ( + + + + + + + ); +} + +export function JSRLogo() { + return ( + + + + ); +} + +export function JSLogo() { + return ( + + + + ); +} diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx index a69dda63..559e28a8 100644 --- a/docs/src/pages/index.tsx +++ b/docs/src/pages/index.tsx @@ -12,64 +12,14 @@ import MarkdownWrapper from "@site/src/components/MarkdownWrapper"; import { CheckCircleIcon, LinkIcon } from "lucide-react"; import { Contributors } from "@site/src/components/Contributors"; import { Sponsors } from "@site/src/components/Sponsors"; - -export function GithubLogo() { - return ( - - - - ); -} - -export function NPMLogo() { - return ( - - - - - - - ); -} - -export function JSRLogo() { - return ( - - - - ); -} +import { + ExpressLogo, + FastifyLogo, + GithubLogo, + JSRLogo, + NPMLogo, + TSLogo, +} from "@site/src/pages/_logos"; function HeroButton({ href, children }) { return ( @@ -86,11 +36,11 @@ function FeatureListItem({ to, title }) { return (
  • - - + + {title} @@ -150,17 +100,17 @@ function Features() { ]; return ( -
    -
    -

    Supported Grants

    +
    +
    + Supported Grants
      {grants.map(({ to, title }) => { return ; })}
    -
    -

    Implemented RFCs

    +
    + Implemented RFCs
      {rfcs.map(({ to, title }) => { return ; @@ -171,6 +121,50 @@ function Features() { ); } +export function SectionTitle({ children }) { + return

      {children}

      ; +} + +export function Adapters() { + const adapters = [ + { + name: "ExpressJS", + logo: , + href: "/docs/adapters/express", + }, + { + name: "FastifyJS", + logo: , + href: "/docs/adapters/fastify", + }, + { + name: "Vanilla JS/TS", + logo: , + href: "/docs/adapters/vanilla", + }, + ] as const; + + return ( +
      + Built in Adapters +
      + {adapters.map(({ name, logo, href }) => { + return ( + + {logo} + {name} + + ); + })} +
      +
      + ); +} + export default function Home() { const { siteConfig } = useDocusaurusContext(); return ( @@ -196,51 +190,34 @@ export default function Home() {
    - - - -
    -
    - - - - - - - - - +
    + Contributors +
    + +
    + Sponsors +
    +
    - + +
    -

    Install

    + Install
    -
    -

    - Entities and Repositories{" "} - +

    +
    @@ -250,37 +227,54 @@ export default function Home() {
    -

    - The Authorization Server{" "} - + + The Authorization Server + -

    +
    -
    -

    - Which Grant?{" "} - +

    +
    +
    -
    -

    Contributors

    -
    - -
    -

    Sponsors

    -
    - -
    +
    + Source Code + - +
    +
    ); } diff --git a/docs/static/favicon-16x16.png b/docs/static/favicon-16x16.png new file mode 100644 index 00000000..78a8124e Binary files /dev/null and b/docs/static/favicon-16x16.png differ diff --git a/docs/static/favicon-32x32.png b/docs/static/favicon-32x32.png new file mode 100644 index 00000000..8634f7be Binary files /dev/null and b/docs/static/favicon-32x32.png differ diff --git a/docs/static/favicon.ico b/docs/static/favicon.ico new file mode 100644 index 00000000..e829d7ca Binary files /dev/null and b/docs/static/favicon.ico differ diff --git a/docs/static/img/favicon.ico b/docs/static/img/favicon.ico deleted file mode 100644 index 4b63061e..00000000 Binary files a/docs/static/img/favicon.ico and /dev/null differ