Skip to content

Commit

Permalink
feat: add @ory/nextjs package
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-jonas committed Nov 29, 2024
1 parent 6913bca commit 4c4c30e
Show file tree
Hide file tree
Showing 47 changed files with 3,144 additions and 165 deletions.
18 changes: 18 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
flag_management:
default_rules:
carryforward: true
statuses:
- type: project
target: auto
threshold: 1%
- type: patch
target: 90%
individual_flags:
- name: "@ory/elements-react"
paths:
- packages/elements-react
carryforward: true
- name: "@ory/nextjs"
paths:
- packages/nextjs
carryforward: true
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ jobs:
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
codecov_yml_path: .github/codecov.yml
934 changes: 769 additions & 165 deletions package-lock.json

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions packages/nextjs/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// "extends": ["../../.eslintrc.base.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": "error"
}
}
]
}
17 changes: 17 additions & 0 deletions packages/nextjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# nextjs

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build @ory/nextjs` to build the library.

## Developing

Run `nx dev @ory/nextjs` to watch the source code for changes and continuously
build the library.

## Running unit tests

Run `nx test @ory/nextjs` to execute the unit tests via
[Jest](https://jestjs.io).
15 changes: 15 additions & 0 deletions packages/nextjs/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0

/* eslint-disable */
export default {
displayName: "nextjs",
preset: "../../jest.preset.js",
testEnvironment: "node",
transform: {
"^.+\\.[tj]s$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.spec.json" }],
},
collectCoverageFrom: ["src/**/*.ts", "src/**/*.js"],
moduleFileExtensions: ["ts", "js", "html"],
coverageDirectory: "../../coverage/packages/nextjs",
}
73 changes: 73 additions & 0 deletions packages/nextjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "@ory/nextjs",
"version": "0.0.1",
"type": "commonjs",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"private": false,
"dependencies": {
"@ory/client-fetch": "^1.15.6",
"cookie": "^1.0.1",
"psl": "^1.10.0",
"set-cookie-parser": "^2.7.1"
},
"devDependencies": {
"@types/cookie": "^0.6.0",
"@types/psl": "^1.1.3",
"@types/set-cookie-parser": "^2.4.10",
"babel-jest": "^29.7.0",
"jest-esm-transformer": "^1.0.0",
"tsup": "8.3.0"
},
"keywords": [
"ory",
"auth",
"react",
"passwordless",
"login",
"user management",
"permissions",
"authentication",
"nextjs",
"vercel",
"app router",
"pages router"
],
"peerDependencies": {
"next": ">=13.1.0",
"react": ">=16.0.0"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./middleware": {
"types": "./dist/middleware/index.d.ts",
"import": "./dist/middleware/index.mjs",
"require": "./dist/middleware/index.js"
},
"./app": {
"types": "./dist/app/index.d.ts",
"import": "./dist/app/index.mjs",
"require": "./dist/app/index.js"
},
"./pages": {
"types": "./dist/pages/index.d.ts",
"import": "./dist/pages/index.mjs",
"require": "./dist/pages/index.js"
}
},
"typesVersions": {
"*": {
"index": [
"./dist/index.d.ts"
],
"middleware": [
"./dist/middleware/index.d.ts"
]
}
}
}
30 changes: 30 additions & 0 deletions packages/nextjs/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@ory/nextjs",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/nextjs/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"command": "tsup --clean --dts",
"options": {
"cwd": "packages/nextjs"
}
},
"dev": {
"command": "tsup --watch --dts",
"options": {
"cwd": "packages/nextjs"
}
},
"test": {
"executor": "@nx/jest:jest",
"dependsOn": ["build"],
"options": {
"jestConfig": "packages/nextjs/jest.config.ts",
"coverage": true,
"coverageReporters": ["text", "cobertura"]
}
}
}
}
15 changes: 15 additions & 0 deletions packages/nextjs/src/app/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import { Configuration, FrontendApi } from "@ory/client-fetch"

Check warning on line 4 in packages/nextjs/src/app/client.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/client.ts#L4

Added line #L4 was not covered by tests

import { orySdkUrl } from "../utils/sdk"

Check warning on line 6 in packages/nextjs/src/app/client.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/client.ts#L6

Added line #L6 was not covered by tests

export const serverSideFrontendClient = new FrontendApi(

Check warning on line 8 in packages/nextjs/src/app/client.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/client.ts#L8

Added line #L8 was not covered by tests
new Configuration({
headers: {
Accept: "application/json",
},
basePath: orySdkUrl(),
}),
)
64 changes: 64 additions & 0 deletions packages/nextjs/src/app/flow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import { redirect, RedirectType } from "next/navigation"
import { FlowType, handleFlowError } from "@ory/client-fetch"

Check warning on line 5 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L4-L5

Added lines #L4 - L5 were not covered by tests

import { getPublicUrl, onRedirect } from "./utils"

Check warning on line 7 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L7

Added line #L7 was not covered by tests
import { QueryParams } from "../types"
import { guessPotentiallyProxiedOrySdkUrl } from "../utils/sdk"
import { onValidationError } from "../utils/utils"
import { rewriteJsonResponse } from "../utils/rewrite"

Check warning on line 11 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L9-L11

Added lines #L9 - L11 were not covered by tests
import * as runtime from "@ory/client-fetch/src/runtime"

export async function getFlow<T extends object>(

Check warning on line 14 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L14

Added line #L14 was not covered by tests
params: QueryParams | Promise<QueryParams>,
fetchFlowRaw: () => Promise<runtime.ApiResponse<T>>,
flowType: FlowType,
): Promise<T | null | void> {
const p = await params

Check warning on line 19 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L19

Added line #L19 was not covered by tests

// Guess our own public url using Next.js helpers. We need the hostname, port, and protocol.
const knownProxiedUrl = await getPublicUrl()

Check warning on line 22 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L22

Added line #L22 was not covered by tests

const onRestartFlow = () => {
return redirect(

Check warning on line 25 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L24-L25

Added lines #L24 - L25 were not covered by tests
new URL(
"/self-service/" +
flowType.toString() +
"/browser?" +
params.toString(),
guessPotentiallyProxiedOrySdkUrl({
knownProxiedUrl,
}),
).toString(),
RedirectType.replace,
)
}

if (!p["flow"]) {
onRestartFlow()
return

Check warning on line 41 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L40-L41

Added lines #L40 - L41 were not covered by tests
}

try {
const rawResponse = await fetchFlowRaw()
return await rawResponse

Check warning on line 46 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L44-L46

Added lines #L44 - L46 were not covered by tests
.value()
.then(
(v: T): T =>
rewriteJsonResponse(

Check warning on line 50 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L49-L50

Added lines #L49 - L50 were not covered by tests
v,
guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl }),
),
)
} catch (error) {
const errorHandler = handleFlowError({

Check warning on line 56 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L56

Added line #L56 was not covered by tests
onValidationError,
onRestartFlow,
onRedirect: onRedirect,
})
await errorHandler(error)
return null

Check warning on line 62 in packages/nextjs/src/app/flow.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/flow.ts#L61-L62

Added lines #L61 - L62 were not covered by tests
}
}
10 changes: 10 additions & 0 deletions packages/nextjs/src/app/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0
"use server"

export { getLoginFlow } from "./login"
export { getRegistrationFlow } from "./registration"
export { getRecoveryFlow } from "./recovery"
export { getVerificationFlow } from "./verification"

Check warning on line 8 in packages/nextjs/src/app/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/index.ts#L5-L8

Added lines #L5 - L8 were not covered by tests

export type { OryPageParams } from "./utils"
13 changes: 13 additions & 0 deletions packages/nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0
import { PropsWithChildren } from "react"

import "@ory/elements-react/theme/styles.css"

export default async function AuthLayout({ children }: PropsWithChildren) {
return (
<main className="p-4 pb-8 flex items-center justify-center flex-col gap-8 min-h-screen">
{children}
</main>
)
}
53 changes: 53 additions & 0 deletions packages/nextjs/src/app/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright © 2024 Ory Corp
// SPDX-License-Identifier: Apache-2.0
import { FlowType, LoginFlow } from "@ory/client-fetch"

Check warning on line 3 in packages/nextjs/src/app/login.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/login.ts#L3

Added line #L3 was not covered by tests

import { initOverrides, QueryParams } from "../types"
import { serverSideFrontendClient } from "./client"
import { getFlow } from "./flow"
import { toFlowParams } from "./utils"

Check warning on line 8 in packages/nextjs/src/app/login.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/login.ts#L5-L8

Added lines #L5 - L8 were not covered by tests

/**
* Use this method in an app router page to fetch an existing login flow or to create a new one. This method works with server-side rendering.
*
* ```
* import { Login } from "@ory/elements-react/theme"
* import { getLoginFlow, OryPageParams } from "@ory/nextjs/app"
* import { enhanceConfig } from "@ory/nextjs"
*
* import config from "@/ory.config"
* import CardHeader from "@/app/auth/login/card-header"
*
* export default async function LoginPage(props: OryPageParams) {
* const flow = await getLoginFlow(props.searchParams)
*
* if (!flow) {
* return null
* }
*
* return (
* <Login
* flow={flow}
* config={enhanceConfig(config)}
* components={{
* Card: {
* Header: CardHeader,
* },
* }}
* />
* )
* }
* ```
*
* @param params The query parameters of the request.
*/
export async function getLoginFlow(

Check warning on line 44 in packages/nextjs/src/app/login.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/login.ts#L44

Added line #L44 was not covered by tests
params: QueryParams | Promise<QueryParams>,
): Promise<LoginFlow | null | void> {
const p = await toFlowParams(await params)
return getFlow(

Check warning on line 48 in packages/nextjs/src/app/login.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/login.ts#L47-L48

Added lines #L47 - L48 were not covered by tests
params,
() => serverSideFrontendClient.getLoginFlowRaw(p, initOverrides),

Check warning on line 50 in packages/nextjs/src/app/login.ts

View check run for this annotation

Codecov / codecov/patch

packages/nextjs/src/app/login.ts#L50

Added line #L50 was not covered by tests
FlowType.Login,
)
}
Loading

0 comments on commit 4c4c30e

Please sign in to comment.