From a17fea02e3a13cdab0f6fadea0422d7dd392c422 Mon Sep 17 00:00:00 2001 From: iaco Date: Tue, 8 Oct 2024 10:25:19 +0100 Subject: [PATCH] replace `user.app_metadata.requires_mfa` with `/authorize?screen_hint=mfa` --- app/api/auth/[auth0]/route.ts | 24 ++----- llm/components/conditional-purchase.tsx | 89 +++++++------------------ llm/tools/add-conditional-purchase.tsx | 36 ++-------- sdk/auth0/mgmt.ts | 27 ++------ 4 files changed, 43 insertions(+), 133 deletions(-) diff --git a/app/api/auth/[auth0]/route.ts b/app/api/auth/[auth0]/route.ts index feb7686..29f25a2 100644 --- a/app/api/auth/[auth0]/route.ts +++ b/app/api/auth/[auth0]/route.ts @@ -2,13 +2,7 @@ import { NextApiRequest, NextApiResponse } from "next"; import { handle3rdPartyParams } from "@/sdk/auth0/3rd-party-apis"; import { linkUser } from "@/sdk/auth0/mgmt"; -import { - getSession, - handleAuth, - handleCallback, - handleLogin, - LoginOptions, -} from "@auth0/nextjs-auth0"; +import { getSession, handleAuth, handleCallback, handleLogin, LoginOptions } from "@auth0/nextjs-auth0"; export const GET = handleAuth({ login: async (req: NextApiRequest, res: NextApiResponse) => { @@ -18,8 +12,10 @@ export const GET = handleAuth({ const url = new URL(req.url!); const thirdPartyApi = url.searchParams.get("3rdPartyApi") || ""; const linkWith = url.searchParams.get("linkWith"); + const screenHint = url.searchParams.get("screenHint"); const authorizationParams = { + ...(screenHint && { screen_hint: screenHint }), ...(thirdPartyApi && (await handle3rdPartyParams(thirdPartyApi))), ...(linkWith && { connection: linkWith, @@ -32,9 +28,7 @@ export const GET = handleAuth({ async getLoginState(_req: any, options: LoginOptions) { if (linkWith) { // store user id to be used during linking account from next login callback - return ( - user && { primaryUserId: user.sub, secondaryProvider: linkWith } - ); + return user && { primaryUserId: user.sub, secondaryProvider: linkWith }; } return {}; @@ -42,11 +36,7 @@ export const GET = handleAuth({ }); }, callback: handleCallback({ - afterCallback: async ( - _req: any, - session: any, - state: { [key: string]: any } - ) => { + afterCallback: async (_req: any, session: any, state: { [key: string]: any }) => { const { primaryUserId, secondaryProvider } = state; const { user } = session; @@ -60,9 +50,7 @@ export const GET = handleAuth({ }); // force a silent login to get a fresh session for the updated user profile - state.returnTo = `/api/auth/login?returnTo=${encodeURI( - state.returnTo - )}`; + state.returnTo = `/api/auth/login?returnTo=${encodeURI(state.returnTo)}`; } return session; diff --git a/llm/components/conditional-purchase.tsx b/llm/components/conditional-purchase.tsx index 215ed3b..cd330cc 100644 --- a/llm/components/conditional-purchase.tsx +++ b/llm/components/conditional-purchase.tsx @@ -7,33 +7,18 @@ import { CancelRedIcon, CheckGreenIcon, TaskIcon } from "@/components/icons"; import Loader from "@/components/loader"; import { ConditionalPurchase as ConditionalPurchaseType } from "@/lib/db/conditional-purchases"; import { getConditionalPurchaseById } from "@/llm/actions/conditional-purchases"; -import { - isGuardianEnrolled, - requireGuardianEnrollment, -} from "@/sdk/auth0/mgmt"; +import { isGuardianEnrolled } from "@/sdk/auth0/mgmt"; import WarningWrapper from "./warning-wrapper"; -export function ConditionalPurchase({ - id, - isMFAEnrolled, -}: { - id: string; - isMFAEnrolled: boolean; -}) { +export function ConditionalPurchase({ id, isMFAEnrolled }: { id: string; isMFAEnrolled: boolean }) { const [isWorking, setIsWorking] = useState(true); const [simulating, setSimulating] = useState(false); const [isEnrolled, setIsEnrolled] = useState(isMFAEnrolled); - const [conditionalPurchase, setConditionalPurchase] = - useState(null); + const [conditionalPurchase, setConditionalPurchase] = useState(null); const checkGuardianEnrollment = useCallback(async () => { const isEnrolled = await isGuardianEnrolled(); - - if (!isEnrolled) { - await requireGuardianEnrollment(); - } - setIsEnrolled(isEnrolled); }, []); @@ -68,18 +53,15 @@ export function ConditionalPurchase({ return (
-

- Action Required: Setup Async Authentication -

+

Action Required: Setup Async Authentication

- Please enroll to Auth0 Guardian so we can notify you when the - condition is met. This is necessary to secure your future - transaction. + Please enroll to Auth0 Guardian so we can notify you when the condition is met. This is necessary to secure + your future transaction.

Enroll @@ -122,10 +104,7 @@ export function ConditionalPurchase({ {!simulating && (
To simulate the agent executing the task, please click{" "} - . @@ -142,22 +121,16 @@ export function ConditionalPurchase({
-
- Buy {conditionalPurchase.symbol} -
+
Buy {conditionalPurchase.symbol}
- Created{" "} - {formatRelative(conditionalPurchase.created_at, new Date())} + Created {formatRelative(conditionalPurchase.created_at, new Date())}
- If {conditionalPurchase.metric} {conditionalPurchase.operator}{" "} - {conditionalPurchase.threshold} -
-
- Condition + If {conditionalPurchase.metric} {conditionalPurchase.operator} {conditionalPurchase.threshold}
+
Condition
@@ -166,10 +139,8 @@ export function ConditionalPurchase({
- Task: Buy {conditionalPurchase.quantity} $ - {conditionalPurchase.symbol} shares if{" "} - {conditionalPurchase.metric} {conditionalPurchase.operator}{" "} - {conditionalPurchase.threshold} + Task: Buy {conditionalPurchase.quantity} ${conditionalPurchase.symbol} shares if{" "} + {conditionalPurchase.metric} {conditionalPurchase.operator} {conditionalPurchase.threshold}
@@ -183,22 +154,17 @@ export function ConditionalPurchase({
- Buy {conditionalPurchase.quantity} shares of{" "} - {conditionalPurchase.symbol} + Buy {conditionalPurchase.quantity} shares of {conditionalPurchase.symbol}
- Created{" "} - {formatRelative(conditionalPurchase.created_at, new Date())} + Created {formatRelative(conditionalPurchase.created_at, new Date())}
- If {conditionalPurchase.metric} {conditionalPurchase.operator}{" "} - {conditionalPurchase.threshold} -
-
- Condition + If {conditionalPurchase.metric} {conditionalPurchase.operator} {conditionalPurchase.threshold}
+
Condition
@@ -207,8 +173,7 @@ export function ConditionalPurchase({
- The purchase was{" "} - CANCELED on{" "} + The purchase was CANCELED on{" "} {format(conditionalPurchase.updated_at, "PPPP p")}.
@@ -223,22 +188,17 @@ export function ConditionalPurchase({
- Buy {conditionalPurchase.quantity} shares of{" "} - {conditionalPurchase.symbol} + Buy {conditionalPurchase.quantity} shares of {conditionalPurchase.symbol}
- Created{" "} - {formatRelative(conditionalPurchase.created_at, new Date())} + Created {formatRelative(conditionalPurchase.created_at, new Date())}
- If {conditionalPurchase.metric} {conditionalPurchase.operator}{" "} - {conditionalPurchase.threshold} -
-
- Condition + If {conditionalPurchase.metric} {conditionalPurchase.operator} {conditionalPurchase.threshold}
+
Condition
@@ -247,8 +207,7 @@ export function ConditionalPurchase({
- The purchase was{" "} - COMPLETED on{" "} + The purchase was COMPLETED on{" "} {format(conditionalPurchase.updated_at, "PPPP p")}.
diff --git a/llm/tools/add-conditional-purchase.tsx b/llm/tools/add-conditional-purchase.tsx index 18f6107..40e0cd2 100644 --- a/llm/tools/add-conditional-purchase.tsx +++ b/llm/tools/add-conditional-purchase.tsx @@ -8,10 +8,7 @@ import { defineTool } from "@/llm/ai-helpers"; import { ConditionalPurchase } from "@/llm/components/conditional-purchase"; import * as serialization from "@/llm/components/serialization"; import { getHistory } from "@/llm/utils"; -import { - isGuardianEnrolled, - requireGuardianEnrollment, -} from "@/sdk/auth0/mgmt"; +import { isGuardianEnrolled } from "@/sdk/auth0/mgmt"; import { getUser, withFGA } from "@/sdk/fga"; import { withCheckPermission } from "@/sdk/fga/vercel-ai/with-check-permission"; @@ -36,23 +33,11 @@ export default defineTool("add_conditional_purchase", () => { 2. 'Buy 10 shares of ZEKO but only when its P/E > 0' would map to the same inputs. 3. 'Buy 100 shares of Tesla when its price is less than or equal to $1000' maps to {symbol: 'TSLA', quantity: 100, metric: 'price', operator: '<=', threshold: 1000}.`, parameters: z.object({ - symbol: z - .string() - .describe( - "The name or ticker symbol of the stock (e.g., 'Zeko Technologies' or ZEKO)." - ), + symbol: z.string().describe("The name or ticker symbol of the stock (e.g., 'Zeko Technologies' or ZEKO)."), quantity: z.number().describe("Number of shares to buy."), - metric: z - .enum(["P/E", "EPS", "P/B", "D/E", "ROE", "RSI", "price"]) - .describe("The financial metric to monitor."), - operator: z - .enum(["=", "<", "<=", ">", ">="]) - .describe("The comparison operator to evaluate the condition."), - threshold: z - .number() - .describe( - "The threshold value of the financial variable that triggers the buy action." - ), + metric: z.enum(["P/E", "EPS", "P/B", "D/E", "ROE", "RSI", "price"]).describe("The financial metric to monitor."), + operator: z.enum(["=", "<", "<=", ">", ">="]).describe("The comparison operator to evaluate the condition."), + threshold: z.number().describe("The threshold value of the financial variable that triggers the buy action."), }), generate: withCheckPermission( { @@ -70,10 +55,6 @@ export default defineTool("add_conditional_purchase", () => { const hs = headers(); const isEnrolled = await isGuardianEnrolled(); - if (!isEnrolled) { - await requireGuardianEnrollment(); - } - // Store the conditional purchase in Market0 db let conditionalPurchase = await conditionalPurchases.create({ user_id: user.sub, @@ -93,12 +74,7 @@ export default defineTool("add_conditional_purchase", () => { params: { id: conditionalPurchase.id }, }); - return ( - - ); + return ; } ), }; diff --git a/sdk/auth0/mgmt.ts b/sdk/auth0/mgmt.ts index aab6c58..fe19170 100644 --- a/sdk/auth0/mgmt.ts +++ b/sdk/auth0/mgmt.ts @@ -27,22 +27,6 @@ export async function isGuardianEnrolled() { } } -export async function requireGuardianEnrollment() { - try { - const session = await getSession(); - const user_id = session?.user.sub; - - const user = await auth0.users.get({ id: user_id }); - const app_metadata = user.data.app_metadata || {}; - - app_metadata.requires_mfa = true; - - await auth0.users.update({ id: user_id }, { app_metadata }); - } catch (error) { - console.error(error); - } -} - export async function getUser(userId: string) { return auth0.users.get({ id: userId }); } @@ -80,8 +64,11 @@ export async function updateUser( userId: string, { givenName, familyName }: { givenName?: string; familyName?: string } ) { - return auth0.users.update({ id: userId }, { - given_name: givenName ?? undefined, - family_name: familyName ?? undefined, - }); + return auth0.users.update( + { id: userId }, + { + given_name: givenName ?? undefined, + family_name: familyName ?? undefined, + } + ); }