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
File renamed without changes.
13 changes: 6 additions & 7 deletions pages/api/admin-portal.js → pages/api/admin-portal.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { WorkOS } from '@workos-inc/node'
import { WorkOS, type Organization } from '@workos-inc/node'
import type { NextApiRequest, NextApiResponse } from 'next'
import baseURL from '../../lib/baseURL'

const workos = new WorkOS(process.env.WORKOS_API_KEY)
const workos = new WorkOS(process.env.WORKOS_API_KEY!)

const createAuditLogEvents = async (organization) => {
const createAuditLogEvents = async (organization: Organization) => {
for (const action of ['user.signed_in', 'user.signed_out']) {
await workos.auditLogs.createEvent(organization.id, {
action,
Expand All @@ -28,15 +29,13 @@ const createAuditLogEvents = async (organization) => {
}
}

export default async (req, res) => {
export default async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { intent, state } = req.body
const name = `demo-${Date.now()}`
const domains = [`${name}.com`]

const organization = await workos.organizations.createOrganization({
name,
domains,
})

if (intent === 'audit_logs') {
Expand All @@ -51,6 +50,6 @@ export default async (req, res) => {

res.status(200).json({ link })
} catch (e) {
res.status(400).json({ message: e.message })
res.status(400).json({ message: e instanceof Error ? e.message : String(e) })
}
}
18 changes: 0 additions & 18 deletions pages/api/callback.js

This file was deleted.

36 changes: 36 additions & 0 deletions pages/api/callback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { WorkOS } from '@workos-inc/node'
import type { NextApiRequest, NextApiResponse } from 'next'

const workos = new WorkOS(process.env.WORKOS_API_KEY!)
const clientId = process.env.WORKOS_CLIENT_ID!

// State is round-tripped through the OAuth flow as a post-auth redirect
// hint. We treat it as untrusted user input — only allow simple path
// segments and fall back to /app for anything else, otherwise an attacker
// could craft state=//example.com and trigger an open redirect.
const SAFE_STATE_PATTERN = /^[a-z0-9_-]+(?:\/[a-z0-9_-]+)*$/i

const safeRedirectPath = (state: unknown): string => {
if (typeof state !== 'string' || !SAFE_STATE_PATTERN.test(state)) {
return '/app'
}
return `/${state}`
}

export default async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { code, state } = req.query
if (typeof code !== 'string') {
res.status(400).json({ message: 'Invalid code' })
return
}
await workos.sso.getProfileAndToken({
code,
clientId,
})

res.redirect(302, safeRedirectPath(state))
} catch {
res.status(400).json(req.query)
}
}
7 changes: 4 additions & 3 deletions pages/api/magic-link.js → pages/api/magic-link.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { WorkOS } from '@workos-inc/node'
import type { NextApiRequest, NextApiResponse } from 'next'

const workos = new WorkOS(process.env.WORKOS_API_KEY)
const workos = new WorkOS(process.env.WORKOS_API_KEY!)

export default async (req, res) => {
export default async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { email, state } = req.body
const session = await workos.passwordless.createSession({
Expand All @@ -14,6 +15,6 @@ export default async (req, res) => {
await workos.passwordless.sendSession(session.id)
res.status(200).json({ sessionId: session.id })
} catch (e) {
res.status(400).json({ message: e.message })
res.status(400).json({ message: e instanceof Error ? e.message : String(e) })
}
}
21 changes: 0 additions & 21 deletions pages/api/sso.js

This file was deleted.

22 changes: 22 additions & 0 deletions pages/api/sso.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { WorkOS } from '@workos-inc/node'
import type { NextApiRequest, NextApiResponse } from 'next'
import baseURL from '../../lib/baseURL'

const workos = new WorkOS(process.env.WORKOS_API_KEY!)
const clientId = process.env.WORKOS_CLIENT_ID!

export default async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { state } = req.body
const authorizationURL = workos.sso.getAuthorizationUrl({
state,
clientId,
organization: 'org_01G2AMPPHC9712JSRAXKY3Z0K7',
redirectUri: `${baseURL}/api/callback`,
})

res.status(200).json({ authorizationURL })
} catch (e) {
res.status(400).json({ message: e instanceof Error ? e.message : String(e) })
}
}
Loading