From 27f3387741cea85d9606f634903e24acc60e3681 Mon Sep 17 00:00:00 2001 From: Zai Shi Date: Sun, 29 Sep 2024 21:45:15 +0200 Subject: [PATCH 1/6] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc2034b9c..9257bcd93 100644 --- a/README.md +++ b/README.md @@ -110,8 +110,8 @@ pnpm install pnpm run build # reset & start the dependencies (DB, Inbucket, etc.) as Docker containers, seeding the DB with the Prisma schema -pnpm run restart-deps -# pnpm run start-deps +pnpm run start-deps +# pnpm run restart-deps # pnpm run stop-deps # Start the dev server From 23a1f95a891dc3169ef5d296b565e2c88fe5aa57 Mon Sep 17 00:00:00 2001 From: Zai Shi Date: Mon, 30 Sep 2024 15:01:30 -0700 Subject: [PATCH 2/6] fixed maybeFullPage layout --- .../src/components-page/forgot-password.tsx | 27 ++++--- .../src/components-page/password-reset.tsx | 76 ++++++++++--------- 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/packages/stack/src/components-page/forgot-password.tsx b/packages/stack/src/components-page/forgot-password.tsx index 314559cbd..4cf1ac976 100644 --- a/packages/stack/src/components-page/forgot-password.tsx +++ b/packages/stack/src/components-page/forgot-password.tsx @@ -3,7 +3,7 @@ import { yupResolver } from "@hookform/resolvers/yup"; import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises"; -import { Button, Input, Label, StyledLink, Typography } from "@stackframe/stack-ui"; +import { Button, Input, Label, StyledLink, Typography, cn } from "@stackframe/stack-ui"; import { useState } from "react"; import { useForm } from "react-hook-form"; import * as yup from "yup"; @@ -76,16 +76,23 @@ export function ForgotPassword(props: { fullPage?: boolean }) { return ( -
- {t("Reset Your Password")} - - {t("Don't need to reset?")}{" "} - - {t("Sign in")} - - +
+
+ {t("Reset Your Password")} + + {t("Don't need to reset?")}{" "} + + {t("Sign in")} + + +
+
+ setSent(true)} /> +
- setSent(true)} /> ); }; diff --git a/packages/stack/src/components-page/password-reset.tsx b/packages/stack/src/components-page/password-reset.tsx index 5641ccf26..24c1494c5 100644 --- a/packages/stack/src/components-page/password-reset.tsx +++ b/packages/stack/src/components-page/password-reset.tsx @@ -6,7 +6,7 @@ import { getPasswordError } from "@stackframe/stack-shared/dist/helpers/password import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { cacheFunction } from "@stackframe/stack-shared/dist/utils/caches"; import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises"; -import { Button, Label, PasswordInput, Typography } from "@stackframe/stack-ui"; +import { Button, Label, PasswordInput, Typography, cn } from "@stackframe/stack-ui"; import React, { useState } from "react"; import { useForm } from "react-hook-form"; import * as yup from "yup"; @@ -74,43 +74,49 @@ export default function PasswordResetForm(props: { ); } + return ( -
- {t("Reset Your Password")} +
+
+ {t("Reset Your Password")} +
+ +
runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))} + noValidate + > + + { + clearErrors('password'); + clearErrors('passwordRepeat'); + }} + /> + + + + { + clearErrors('password'); + clearErrors('passwordRepeat'); + }} + /> + + + +
- -
runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))} - noValidate - > - - { - clearErrors('password'); - clearErrors('passwordRepeat'); - }} - /> - - - - { - clearErrors('password'); - clearErrors('passwordRepeat'); - }} - /> - - - - ); } From 584b5e4faf18eb3992e902188ece869fa70c922a Mon Sep 17 00:00:00 2001 From: Zai Shi Date: Mon, 30 Sep 2024 15:11:51 -0700 Subject: [PATCH 3/6] fixed current user docs --- docs/fern/docs/pages/sdk/current-user.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fern/docs/pages/sdk/current-user.mdx b/docs/fern/docs/pages/sdk/current-user.mdx index d3c898497..9c51abbed 100644 --- a/docs/fern/docs/pages/sdk/current-user.mdx +++ b/docs/fern/docs/pages/sdk/current-user.mdx @@ -1,5 +1,5 @@ --- -slug: sdk/user +slug: sdk/current-user --- ## `CurrentUser` and `CurrentServerUser` From ce46c16e6de21b7e6e75a959e338f0ae062d0685 Mon Sep 17 00:00:00 2001 From: Konstantin Wohlwend Date: Mon, 30 Sep 2024 20:05:45 -0700 Subject: [PATCH 4/6] chore: update package versions --- apps/backend/CHANGELOG.md | 8 ++++++++ apps/backend/package.json | 2 +- apps/dashboard/CHANGELOG.md | 10 ++++++++++ apps/dashboard/package.json | 2 +- apps/e2e/CHANGELOG.md | 7 +++++++ apps/e2e/package.json | 2 +- apps/oauth-mock-server/CHANGELOG.md | 6 ++++++ apps/oauth-mock-server/package.json | 2 +- docs/CHANGELOG.md | 6 ++++++ docs/package.json | 2 +- examples/cjs-test/CHANGELOG.md | 7 +++++++ examples/cjs-test/package.json | 2 +- examples/demo/CHANGELOG.md | 9 +++++++++ examples/demo/package.json | 2 +- examples/docs-examples/CHANGELOG.md | 9 +++++++++ examples/docs-examples/package.json | 2 +- examples/e-commerce/CHANGELOG.md | 7 +++++++ examples/e-commerce/package.json | 2 +- examples/express-proxied-server/CHANGELOG.md | 2 ++ examples/express-proxied-server/package.json | 2 +- examples/middleware/CHANGELOG.md | 7 +++++++ examples/middleware/package.json | 2 +- examples/partial-prerendering/CHANGELOG.md | 7 +++++++ examples/partial-prerendering/package.json | 2 +- examples/supabase/CHANGELOG.md | 7 +++++++ examples/supabase/package.json | 2 +- packages/init-stack/CHANGELOG.md | 2 ++ packages/init-stack/package.json | 2 +- packages/stack-emails/CHANGELOG.md | 7 +++++++ packages/stack-emails/package.json | 2 +- packages/stack-proxy/CHANGELOG.md | 7 +++++++ packages/stack-proxy/package.json | 2 +- packages/stack-sc/CHANGELOG.md | 2 ++ packages/stack-sc/package.json | 2 +- packages/stack-shared/CHANGELOG.md | 6 ++++++ packages/stack-shared/package.json | 2 +- packages/stack-ui/CHANGELOG.md | 6 ++++++ packages/stack-ui/package.json | 2 +- packages/stack/CHANGELOG.md | 9 +++++++++ packages/stack/package.json | 2 +- 40 files changed, 151 insertions(+), 20 deletions(-) diff --git a/apps/backend/CHANGELOG.md b/apps/backend/CHANGELOG.md index 5fc999301..b26572cbe 100644 --- a/apps/backend/CHANGELOG.md +++ b/apps/backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @stackframe/stack-backend +## 2.6.1 + +### Patch Changes + +- Bugfixes + - @stackframe/stack-emails@2.6.1 + - @stackframe/stack-shared@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/apps/backend/package.json b/apps/backend/package.json index cdc977eb1..0189b0810 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-backend", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "clean": "rimraf .next && rimraf node_modules", diff --git a/apps/dashboard/CHANGELOG.md b/apps/dashboard/CHANGELOG.md index 3982e15d8..175b5c139 100644 --- a/apps/dashboard/CHANGELOG.md +++ b/apps/dashboard/CHANGELOG.md @@ -1,5 +1,15 @@ # @stackframe/stack-dashboard +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + - @stackframe/stack-emails@2.6.1 + - @stackframe/stack-shared@2.6.1 + - @stackframe/stack-ui@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 9e3728dc9..6b3dc9a7a 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-dashboard", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "clean": "rimraf .next && rimraf node_modules", diff --git a/apps/e2e/CHANGELOG.md b/apps/e2e/CHANGELOG.md index 1df0541be..3834e481d 100644 --- a/apps/e2e/CHANGELOG.md +++ b/apps/e2e/CHANGELOG.md @@ -1,5 +1,12 @@ # e2e-tests +## 2.6.1 + +### Patch Changes + +- Bugfixes + - @stackframe/stack-shared@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/apps/e2e/package.json b/apps/e2e/package.json index 67d064b26..4b4adec6a 100644 --- a/apps/e2e/package.json +++ b/apps/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/e2e-tests", - "version": "2.6.0", + "version": "2.6.1", "private": true, "type": "module", "scripts": { diff --git a/apps/oauth-mock-server/CHANGELOG.md b/apps/oauth-mock-server/CHANGELOG.md index 54c75f737..2fcd65880 100644 --- a/apps/oauth-mock-server/CHANGELOG.md +++ b/apps/oauth-mock-server/CHANGELOG.md @@ -1,5 +1,11 @@ # @stackframe/oauth-mock-server +## 2.6.1 + +### Patch Changes + +- @stackframe/stack-shared@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/apps/oauth-mock-server/package.json b/apps/oauth-mock-server/package.json index 524a11b5f..083d8b1e3 100644 --- a/apps/oauth-mock-server/package.json +++ b/apps/oauth-mock-server/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/oauth-mock-server", - "version": "2.6.0", + "version": "2.6.1", "private": true, "main": "index.js", "scripts": { diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 525b9a3b3..97bcc25ce 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,11 @@ # @stackframe/docs +## 2.6.1 + +### Patch Changes + +- Bugfixes + ## 2.6.0 ### Minor Changes diff --git a/docs/package.json b/docs/package.json index d06ed7eaf..82008ac32 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/docs", - "version": "2.6.0", + "version": "2.6.1", "description": "", "main": "index.js", "private": true, diff --git a/examples/cjs-test/CHANGELOG.md b/examples/cjs-test/CHANGELOG.md index 401050769..09e8f5269 100644 --- a/examples/cjs-test/CHANGELOG.md +++ b/examples/cjs-test/CHANGELOG.md @@ -1,5 +1,12 @@ # cjs-test +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/cjs-test/package.json b/examples/cjs-test/package.json index c487ef862..a5ea709e0 100644 --- a/examples/cjs-test/package.json +++ b/examples/cjs-test/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/example-cjs-test", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "dev": "next dev --port 8110", diff --git a/examples/demo/CHANGELOG.md b/examples/demo/CHANGELOG.md index a09ffef53..133a64461 100644 --- a/examples/demo/CHANGELOG.md +++ b/examples/demo/CHANGELOG.md @@ -1,5 +1,14 @@ # demo-app +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + - @stackframe/stack-shared@2.6.1 + - @stackframe/stack-ui@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/demo/package.json b/examples/demo/package.json index 3172890b8..bd8b28bba 100644 --- a/examples/demo/package.json +++ b/examples/demo/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/example-demo-app", - "version": "2.6.0", + "version": "2.6.1", "description": "", "private": true, "scripts": { diff --git a/examples/docs-examples/CHANGELOG.md b/examples/docs-examples/CHANGELOG.md index 403b81ffc..f96d9cb81 100644 --- a/examples/docs-examples/CHANGELOG.md +++ b/examples/docs-examples/CHANGELOG.md @@ -1,5 +1,14 @@ # demo-app +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + - @stackframe/stack-shared@2.6.1 + - @stackframe/stack-ui@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/docs-examples/package.json b/examples/docs-examples/package.json index 6fe8fd553..286afdd29 100644 --- a/examples/docs-examples/package.json +++ b/examples/docs-examples/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/docs-examples", - "version": "2.6.0", + "version": "2.6.1", "description": "", "private": true, "scripts": { diff --git a/examples/e-commerce/CHANGELOG.md b/examples/e-commerce/CHANGELOG.md index 86997b113..39246da0d 100644 --- a/examples/e-commerce/CHANGELOG.md +++ b/examples/e-commerce/CHANGELOG.md @@ -1,5 +1,12 @@ # @stackframe/e-commerce-demo +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/e-commerce/package.json b/examples/e-commerce/package.json index debda4c4a..3c94599f0 100644 --- a/examples/e-commerce/package.json +++ b/examples/e-commerce/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/e-commerce-demo", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "dev": "next dev --port 8111", diff --git a/examples/express-proxied-server/CHANGELOG.md b/examples/express-proxied-server/CHANGELOG.md index af8a7da4b..276f2a57c 100644 --- a/examples/express-proxied-server/CHANGELOG.md +++ b/examples/express-proxied-server/CHANGELOG.md @@ -1,5 +1,7 @@ # @stackframe/proxied-server-example +## 2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/express-proxied-server/package.json b/examples/express-proxied-server/package.json index 322235038..780aeae37 100644 --- a/examples/express-proxied-server/package.json +++ b/examples/express-proxied-server/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/proxied-server-example", - "version": "2.6.0", + "version": "2.6.1", "private": true, "dependencies": { "express": "^4.19.2", diff --git a/examples/middleware/CHANGELOG.md b/examples/middleware/CHANGELOG.md index 35eb7cb7a..9765fa25f 100644 --- a/examples/middleware/CHANGELOG.md +++ b/examples/middleware/CHANGELOG.md @@ -1,5 +1,12 @@ # middleware-demo +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/middleware/package.json b/examples/middleware/package.json index 481ee8d4b..4ea9022a9 100644 --- a/examples/middleware/package.json +++ b/examples/middleware/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/example-middleware-demo", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "dev": "next dev --port 8112", diff --git a/examples/partial-prerendering/CHANGELOG.md b/examples/partial-prerendering/CHANGELOG.md index 81683c665..e336a864f 100644 --- a/examples/partial-prerendering/CHANGELOG.md +++ b/examples/partial-prerendering/CHANGELOG.md @@ -1,5 +1,12 @@ # partial-prerendering +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/partial-prerendering/package.json b/examples/partial-prerendering/package.json index b27c1cb66..4128cc26f 100644 --- a/examples/partial-prerendering/package.json +++ b/examples/partial-prerendering/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/example-partial-prerendering", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "dev": "next dev --port 8109", diff --git a/examples/supabase/CHANGELOG.md b/examples/supabase/CHANGELOG.md index 0f0d3f936..6b8a5fc89 100644 --- a/examples/supabase/CHANGELOG.md +++ b/examples/supabase/CHANGELOG.md @@ -1,5 +1,12 @@ # @stackframe/example-supabase +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/examples/supabase/package.json b/examples/supabase/package.json index 1f1753a11..d63727b0e 100644 --- a/examples/supabase/package.json +++ b/examples/supabase/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/example-supabase", - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "dev": "next dev", diff --git a/packages/init-stack/CHANGELOG.md b/packages/init-stack/CHANGELOG.md index b130e0717..c47c8d54a 100644 --- a/packages/init-stack/CHANGELOG.md +++ b/packages/init-stack/CHANGELOG.md @@ -1,5 +1,7 @@ # @stackframe/init-stack +## 2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/init-stack/package.json b/packages/init-stack/package.json index c541bce65..fde72183b 100644 --- a/packages/init-stack/package.json +++ b/packages/init-stack/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/init-stack", - "version": "2.6.0", + "version": "2.6.1", "description": "The setup wizard for Stack. https://stack-auth.com", "main": "index.mjs", "bin": "./index.mjs", diff --git a/packages/stack-emails/CHANGELOG.md b/packages/stack-emails/CHANGELOG.md index fbd08a4f0..af61c6380 100644 --- a/packages/stack-emails/CHANGELOG.md +++ b/packages/stack-emails/CHANGELOG.md @@ -1,5 +1,12 @@ # @stackframe/stack-emails +## 2.6.1 + +### Patch Changes + +- @stackframe/stack-shared@2.6.1 +- @stackframe/stack-ui@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/stack-emails/package.json b/packages/stack-emails/package.json index 65be8d66e..80c67ec7d 100644 --- a/packages/stack-emails/package.json +++ b/packages/stack-emails/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-emails", - "version": "2.6.0", + "version": "2.6.1", "main": "./dist/index.js", "types": "./dist/index.d.ts", "private": true, diff --git a/packages/stack-proxy/CHANGELOG.md b/packages/stack-proxy/CHANGELOG.md index 05f6f9485..406208218 100644 --- a/packages/stack-proxy/CHANGELOG.md +++ b/packages/stack-proxy/CHANGELOG.md @@ -1,5 +1,12 @@ # @stackframe/stack-proxy +## 2.6.1 + +### Patch Changes + +- Updated dependencies + - @stackframe/stack@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/stack-proxy/package.json b/packages/stack-proxy/package.json index 52f992a80..6f52888dd 100644 --- a/packages/stack-proxy/package.json +++ b/packages/stack-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-proxy", - "version": "2.6.0", + "version": "2.6.1", "private": true, "type": "module", "scripts": { diff --git a/packages/stack-sc/CHANGELOG.md b/packages/stack-sc/CHANGELOG.md index 83bfe3872..26ad55131 100644 --- a/packages/stack-sc/CHANGELOG.md +++ b/packages/stack-sc/CHANGELOG.md @@ -1,5 +1,7 @@ # @stackframe/stack-sc +## 2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/stack-sc/package.json b/packages/stack-sc/package.json index 3777f90e9..2994ff1ad 100644 --- a/packages/stack-sc/package.json +++ b/packages/stack-sc/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-sc", - "version": "2.6.0", + "version": "2.6.1", "exports": { "./force-react-server": { "types": "./dist/index.react-server.d.ts", diff --git a/packages/stack-shared/CHANGELOG.md b/packages/stack-shared/CHANGELOG.md index dbe0fc40e..836541daa 100644 --- a/packages/stack-shared/CHANGELOG.md +++ b/packages/stack-shared/CHANGELOG.md @@ -1,5 +1,11 @@ # @stackframe/stack-shared +## 2.6.1 + +### Patch Changes + +- @stackframe/stack-sc@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/stack-shared/package.json b/packages/stack-shared/package.json index 9ea6dbcf4..13b3588c8 100644 --- a/packages/stack-shared/package.json +++ b/packages/stack-shared/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-shared", - "version": "2.6.0", + "version": "2.6.1", "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { diff --git a/packages/stack-ui/CHANGELOG.md b/packages/stack-ui/CHANGELOG.md index bdb30d1ef..f674407d5 100644 --- a/packages/stack-ui/CHANGELOG.md +++ b/packages/stack-ui/CHANGELOG.md @@ -1,5 +1,11 @@ # @stackframe/stack-ui +## 2.6.1 + +### Patch Changes + +- @stackframe/stack-shared@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/stack-ui/package.json b/packages/stack-ui/package.json index 8a0cd7c06..5c96cb6eb 100644 --- a/packages/stack-ui/package.json +++ b/packages/stack-ui/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack-ui", - "version": "2.6.0", + "version": "2.6.1", "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { diff --git a/packages/stack/CHANGELOG.md b/packages/stack/CHANGELOG.md index f279bc77d..756cc130c 100644 --- a/packages/stack/CHANGELOG.md +++ b/packages/stack/CHANGELOG.md @@ -1,5 +1,14 @@ # @stackframe/stack +## 2.6.1 + +### Patch Changes + +- Bugfixes + - @stackframe/stack-sc@2.6.1 + - @stackframe/stack-shared@2.6.1 + - @stackframe/stack-ui@2.6.1 + ## 2.6.0 ### Minor Changes diff --git a/packages/stack/package.json b/packages/stack/package.json index f3f695071..88f838558 100644 --- a/packages/stack/package.json +++ b/packages/stack/package.json @@ -1,6 +1,6 @@ { "name": "@stackframe/stack", - "version": "2.6.0", + "version": "2.6.1", "sideEffects": false, "main": "./dist/index.js", "types": "./dist/index.d.ts", From d0b3d6e620660277faad06a46286c1ad8157e1c2 Mon Sep 17 00:00:00 2001 From: Zai Shi Date: Tue, 1 Oct 2024 06:11:00 +0200 Subject: [PATCH 5/6] Fix team creation on the server not automatically adding the current user (#266) * add_current_user => creator_user_id * added more tests * added error checks * removed getIdFromUserIdOrMe --------- Co-authored-by: Konsti Wohlwend --- .../[provider_id]/access-token/crud.tsx | 15 +-- .../app/api/v1/team-member-profiles/crud.tsx | 28 ++--- .../src/app/api/v1/team-memberships/crud.tsx | 19 ++- .../src/app/api/v1/team-permissions/crud.tsx | 6 +- apps/backend/src/app/api/v1/teams/crud.tsx | 33 +++-- apps/backend/src/app/api/v1/users/crud.tsx | 6 +- apps/backend/src/route-handlers/utils.tsx | 15 --- apps/e2e/tests/backend/backend-helpers.ts | 3 +- .../endpoints/api/v1/team-memberships.test.ts | 119 ++++++++++++++++++ .../src/interface/clientInterface.ts | 4 +- .../stack-shared/src/interface/crud/teams.ts | 2 + .../src/interface/serverInterface.ts | 4 +- packages/stack-shared/src/schema-fields.ts | 1 + packages/stack/src/lib/stack-app.ts | 10 +- 14 files changed, 188 insertions(+), 77 deletions(-) delete mode 100644 apps/backend/src/route-handlers/utils.tsx diff --git a/apps/backend/src/app/api/v1/connected-accounts/[user_id]/[provider_id]/access-token/crud.tsx b/apps/backend/src/app/api/v1/connected-accounts/[user_id]/[provider_id]/access-token/crud.tsx index e6d131dd2..7b46b80af 100644 --- a/apps/backend/src/app/api/v1/connected-accounts/[user_id]/[provider_id]/access-token/crud.tsx +++ b/apps/backend/src/app/api/v1/connected-accounts/[user_id]/[provider_id]/access-token/crud.tsx @@ -2,10 +2,9 @@ import { usersCrudHandlers } from "@/app/api/v1/users/crud"; import { getProvider } from "@/oauth"; import { prismaClient } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; -import { getIdFromUserIdOrMe } from "@/route-handlers/utils"; import { KnownErrors } from "@stackframe/stack-shared"; import { connectedAccountAccessTokenCrud } from "@stackframe/stack-shared/dist/interface/crud/oauth"; -import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; +import { userIdOrMeSchema, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { StackAssertionError, StatusError } from "@stackframe/stack-shared/dist/utils/errors"; import { createLazyProxy } from "@stackframe/stack-shared/dist/utils/proxies"; import { extractScopes } from "@stackframe/stack-shared/dist/utils/strings"; @@ -14,12 +13,10 @@ import { extractScopes } from "@stackframe/stack-shared/dist/utils/strings"; export const connectedAccountAccessTokenCrudHandlers = createLazyProxy(() =>createCrudHandlers(connectedAccountAccessTokenCrud, { paramsSchema: yupObject({ provider_id: yupString().required(), - user_id: yupString().required(), + user_id: userIdOrMeSchema.required(), }), async onCreate({ auth, data, params }) { - const userId = getIdFromUserIdOrMe(params.user_id, auth.user); - - if (auth.type === 'client' && auth.user?.id !== userId) { + if (auth.type === 'client' && auth.user?.id !== params.user_id) { throw new StatusError(StatusError.Forbidden, "Client can only access its own connected accounts"); } @@ -32,7 +29,7 @@ export const connectedAccountAccessTokenCrudHandlers = createLazyProxy(() =>crea throw new KnownErrors.OAuthAccessTokenNotAvailableWithSharedOAuthKeys(); } - const user = await usersCrudHandlers.adminRead({ project: auth.project, user_id: userId }); + const user = await usersCrudHandlers.adminRead({ project: auth.project, user_id: params.user_id }); if (!user.oauth_providers.map(x => x.id).includes(params.provider_id)) { throw new KnownErrors.OAuthConnectionNotConnectedToUser(); } @@ -44,7 +41,7 @@ export const connectedAccountAccessTokenCrudHandlers = createLazyProxy(() =>crea projectId: auth.project.id, oAuthProviderConfigId: params.provider_id, projectUserOAuthAccount: { - projectUserId: userId, + projectUserId: params.user_id, }, expiresAt: { // is at least 5 minutes in the future @@ -66,7 +63,7 @@ export const connectedAccountAccessTokenCrudHandlers = createLazyProxy(() =>crea projectId: auth.project.id, oAuthProviderConfigId: params.provider_id, projectUserOAuthAccount: { - projectUserId: userId, + projectUserId: params.user_id, } }, }); diff --git a/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx b/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx index ab22f437e..9a4bb6a9d 100644 --- a/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx +++ b/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx @@ -1,7 +1,6 @@ import { ensureTeamExist, ensureTeamMembershipExists, ensureUserExist, ensureUserTeamPermissionExists } from "@/lib/request-checks"; import { prismaClient } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; -import { getIdFromUserIdOrMe } from "@/route-handlers/utils"; import { Prisma } from "@prisma/client"; import { KnownErrors } from "@stackframe/stack-shared"; import { teamMemberProfilesCrud } from "@stackframe/stack-shared/dist/interface/crud/team-member-profiles"; @@ -33,7 +32,6 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa }), onList: async ({ auth, query }) => { return await prismaClient.$transaction(async (tx) => { - const userId = getIdFromUserIdOrMe(query.user_id, auth.user); if (auth.type === 'client') { // Client can only: // - list users in their own team if they have the $read_members permission @@ -47,7 +45,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa await ensureTeamMembershipExists(tx, { projectId: auth.project.id, teamId: query.team_id, userId: currentUserId }); - if (userId !== currentUserId) { + if (query.user_id !== currentUserId) { await ensureUserTeamPermissionExists(tx, { project: auth.project, teamId: query.team_id, @@ -61,8 +59,8 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa if (query.team_id) { await ensureTeamExist(tx, { projectId: auth.project.id, teamId: query.team_id }); } - if (userId) { - await ensureUserExist(tx, { projectId: auth.project.id, userId: userId }); + if (query.user_id) { + await ensureUserExist(tx, { projectId: auth.project.id, userId: query.user_id }); } } @@ -70,7 +68,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa where: { projectId: auth.project.id, teamId: query.team_id, - projectUserId: userId, + projectUserId: query.user_id, }, orderBy: { createdAt: 'asc', @@ -88,11 +86,9 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa }, onRead: async ({ auth, params }) => { return await prismaClient.$transaction(async (tx) => { - const userId = getIdFromUserIdOrMe(params.user_id, auth.user); - if (auth.type === 'client') { const currentUserId = auth.user?.id ?? throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); - if (userId !== currentUserId) { + if (params.user_id !== currentUserId) { await ensureUserTeamPermissionExists(tx, { project: auth.project, teamId: params.team_id, @@ -104,13 +100,13 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa } } - await ensureTeamMembershipExists(tx, { projectId: auth.project.id, teamId: params.team_id, userId: userId }); + await ensureTeamMembershipExists(tx, { projectId: auth.project.id, teamId: params.team_id, userId: params.user_id }); const db = await tx.teamMember.findUnique({ where: { projectId_projectUserId_teamId: { projectId: auth.project.id, - projectUserId: userId, + projectUserId: params.user_id, teamId: params.team_id, }, }, @@ -119,7 +115,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa if (!db) { // This should never happen because of the check above - throw new KnownErrors.TeamMembershipNotFound(params.team_id, userId); + throw new KnownErrors.TeamMembershipNotFound(params.team_id, params.user_id); } return prismaToCrud(db, await getUserLastActiveAtMillis(db.projectUser.projectUserId, db.projectUser.createdAt)); @@ -127,11 +123,9 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa }, onUpdate: async ({ auth, data, params }) => { return await prismaClient.$transaction(async (tx) => { - const userId = getIdFromUserIdOrMe(params.user_id, auth.user); - if (auth.type === 'client') { const currentUserId = auth.user?.id ?? throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); - if (userId !== currentUserId) { + if (params.user_id !== currentUserId) { throw new StatusError(StatusError.Forbidden, 'Cannot update another user\'s profile'); } } @@ -139,14 +133,14 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa await ensureTeamMembershipExists(tx, { projectId: auth.project.id, teamId: params.team_id, - userId, + userId: params.user_id, }); const db = await tx.teamMember.update({ where: { projectId_projectUserId_teamId: { projectId: auth.project.id, - projectUserId: userId, + projectUserId: params.user_id, teamId: params.team_id, }, }, diff --git a/apps/backend/src/app/api/v1/team-memberships/crud.tsx b/apps/backend/src/app/api/v1/team-memberships/crud.tsx index 03f6e26f3..60b4dc829 100644 --- a/apps/backend/src/app/api/v1/team-memberships/crud.tsx +++ b/apps/backend/src/app/api/v1/team-memberships/crud.tsx @@ -2,7 +2,6 @@ import { ensureTeamExist, ensureTeamMembershipExists, ensureTeamMembershipDoesNo import { isTeamSystemPermission, teamSystemPermissionStringToDBType } from "@/lib/permissions"; import { prismaClient } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; -import { getIdFromUserIdOrMe } from "@/route-handlers/utils"; import { teamMembershipsCrud } from "@stackframe/stack-shared/dist/interface/crud/team-memberships"; import { userIdOrMeSchema, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; import { throwErr } from "@stackframe/stack-shared/dist/utils/errors"; @@ -57,8 +56,6 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl user_id: userIdOrMeSchema.required(), }), onCreate: async ({ auth, params }) => { - const userId = getIdFromUserIdOrMe(params.user_id, auth.user); - await prismaClient.$transaction(async (tx) => { await ensureTeamExist(tx, { projectId: auth.project.id, @@ -68,14 +65,14 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl await ensureTeamMembershipDoesNotExist(tx, { projectId: auth.project.id, teamId: params.team_id, - userId, + userId: params.user_id }); const user = await tx.projectUser.findUnique({ where: { projectId_projectUserId: { projectId: auth.project.id, - projectUserId: userId, + projectUserId: params.user_id, }, }, }); @@ -87,14 +84,14 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl await addUserToTeam(tx, { project: auth.project, teamId: params.team_id, - userId, + userId: params.user_id, type: 'member', }); }); const data = { team_id: params.team_id, - user_id: userId, + user_id: params.user_id, }; await sendTeamMembershipCreatedWebhook({ @@ -105,15 +102,13 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl return data; }, onDelete: async ({ auth, params }) => { - const userId = getIdFromUserIdOrMe(params.user_id, auth.user); - await prismaClient.$transaction(async (tx) => { // Users are always allowed to remove themselves from a team // Only users with the $remove_members permission can remove other users if (auth.type === 'client') { const currentUserId = auth.user?.id ?? throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); - if (userId !== currentUserId) { + if (params.user_id !== currentUserId) { await ensureUserTeamPermissionExists(tx, { project: auth.project, teamId: params.team_id, @@ -128,7 +123,7 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl await ensureTeamMembershipExists(tx, { projectId: auth.project.id, teamId: params.team_id, - userId, + userId: params.user_id, }); await tx.teamMember.delete({ @@ -146,7 +141,7 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl projectId: auth.project.id, data: { team_id: params.team_id, - user_id: userId, + user_id: params.user_id, }, }); }, diff --git a/apps/backend/src/app/api/v1/team-permissions/crud.tsx b/apps/backend/src/app/api/v1/team-permissions/crud.tsx index 078a6b7a9..a433b2b89 100644 --- a/apps/backend/src/app/api/v1/team-permissions/crud.tsx +++ b/apps/backend/src/app/api/v1/team-permissions/crud.tsx @@ -2,7 +2,6 @@ import { grantTeamPermission, listUserTeamPermissions, revokeTeamPermission } fr import { ensureTeamMembershipExists, ensureUserTeamPermissionExists } from "@/lib/request-checks"; import { prismaClient } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; -import { getIdFromUserIdOrMe } from "@/route-handlers/utils"; import { KnownErrors } from "@stackframe/stack-shared"; import { teamPermissionsCrud } from '@stackframe/stack-shared/dist/interface/crud/team-permissions'; import { teamPermissionDefinitionIdSchema, userIdOrMeSchema, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; @@ -53,11 +52,10 @@ export const teamPermissionsCrudHandlers = createLazyProxy(() => createCrudHandl }); }, async onList({ auth, query }) { - const userId = getIdFromUserIdOrMe(query.user_id, auth.user); if (auth.type === 'client') { const currentUserId = auth.user?.id || throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); - if (userId !== currentUserId) { + if (query.user_id !== currentUserId) { throw new StatusError(StatusError.Forbidden, 'Client can only list permissions for their own user. user_id must be either "me" or the ID of the current user'); } } @@ -68,7 +66,7 @@ export const teamPermissionsCrudHandlers = createLazyProxy(() => createCrudHandl project: auth.project, teamId: query.team_id, permissionId: query.permission_id, - userId, + userId: query.user_id, recursive: query.recursive === 'true', }), is_paginated: false, diff --git a/apps/backend/src/app/api/v1/teams/crud.tsx b/apps/backend/src/app/api/v1/teams/crud.tsx index c22ec1382..90d7d58b3 100644 --- a/apps/backend/src/app/api/v1/teams/crud.tsx +++ b/apps/backend/src/app/api/v1/teams/crud.tsx @@ -2,15 +2,14 @@ import { ensureTeamExist, ensureTeamMembershipExists, ensureUserTeamPermissionEx import { sendTeamCreatedWebhook, sendTeamDeletedWebhook, sendTeamUpdatedWebhook } from "@/lib/webhooks"; import { prismaClient } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; -import { getIdFromUserIdOrMe } from "@/route-handlers/utils"; import { Prisma } from "@prisma/client"; import { KnownErrors } from "@stackframe/stack-shared"; import { teamsCrud } from "@stackframe/stack-shared/dist/interface/crud/teams"; import { userIdOrMeSchema, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; +import { validateBase64Image } from "@stackframe/stack-shared/dist/utils/base64"; import { StatusError, throwErr } from "@stackframe/stack-shared/dist/utils/errors"; import { createLazyProxy } from "@stackframe/stack-shared/dist/utils/proxies"; import { addUserToTeam } from "../team-memberships/crud"; -import { validateBase64Image } from "@stackframe/stack-shared/dist/utils/base64"; export function teamPrismaToCrud(prisma: Prisma.TeamGetPayload<{}>) { @@ -28,12 +27,17 @@ export function teamPrismaToCrud(prisma: Prisma.TeamGetPayload<{}>) { export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsCrud, { querySchema: yupObject({ user_id: userIdOrMeSchema.optional().meta({ openapiField: { onlyShowInOperations: ['List'], description: 'Filter for the teams that the user is a member of. Can be either `me` or an ID. Must be `me` in the client API', exampleValue: 'me' } }), - add_current_user: yupString().oneOf(["true", "false"]).optional().meta({ openapiField: { onlyShowInOperations: ['Create'], description: "If to add the current user to the team. If this is not `true`, the newly created team will have no members. Notice that if you didn't specify `add_current_user=true` on the client side, the user cannot join the team again without re-adding them on the server side.", exampleValue: 'true' } }), + /* deprecated, use creator_user_id in the body instead */ + add_current_user: yupString().oneOf(["true", "false"]).optional().meta({ openapiField: { onlyShowInOperations: ['Create'], hidden: true } }), }), paramsSchema: yupObject({ team_id: yupString().uuid().required(), }), onCreate: async ({ query, auth, data }) => { + if (data.creator_user_id && query.add_current_user) { + throw new StatusError(StatusError.BadRequest, "Cannot use both creator_user_id and add_current_user. add_current_user is deprecated, please only use creator_user_id in the body."); + } + if (auth.type === 'client' && !auth.user) { throw new KnownErrors.UserAuthenticationRequired(); } @@ -58,15 +62,27 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC }, }); - if (query.add_current_user === 'true') { + let addUserId: string | undefined; + if (data.creator_user_id) { + if (auth.type === 'client') { + const currentUserId = auth.user?.id ?? throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); + if (data.creator_user_id !== currentUserId) { + throw new StatusError(StatusError.Forbidden, "You cannot add a user to the team as the creator that is not yourself on the client."); + } + } + addUserId = data.creator_user_id; + } else if (query.add_current_user === 'true') { if (!auth.user) { throw new StatusError(StatusError.Unauthorized, "You must be logged in to create a team with the current user as a member."); } + addUserId = auth.user.id; + } + if (addUserId) { await addUserToTeam(tx, { project: auth.project, teamId: db.teamId, - userId: auth.user.id, + userId: addUserId, type: 'creator', }); } @@ -188,11 +204,10 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC }); }, onList: async ({ query, auth }) => { - const userId = getIdFromUserIdOrMe(query.user_id, auth.user); if (auth.type === 'client') { const currentUserId = auth.user?.id || throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); - if (userId !== currentUserId) { + if (query.user_id !== currentUserId) { throw new StatusError(StatusError.Forbidden, 'Client can only list teams for their own user. user_id must be either "me" or the ID of the current user'); } } @@ -200,10 +215,10 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC const db = await prismaClient.team.findMany({ where: { projectId: auth.project.id, - ...userId ? { + ...query.user_id ? { teamMembers: { some: { - projectUserId: userId, + projectUserId: query.user_id, }, }, } : {}, diff --git a/apps/backend/src/app/api/v1/users/crud.tsx b/apps/backend/src/app/api/v1/users/crud.tsx index e677e713a..3993c0ad1 100644 --- a/apps/backend/src/app/api/v1/users/crud.tsx +++ b/apps/backend/src/app/api/v1/users/crud.tsx @@ -542,10 +542,8 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC `${data.display_name}'s Team` : data.primary_email ? `${data.primary_email}'s Team` : - "Personal Team" - }, - query: { - add_current_user: "true", + "Personal Team", + creator_user_id: 'me', }, project: auth.project, user: result, diff --git a/apps/backend/src/route-handlers/utils.tsx b/apps/backend/src/route-handlers/utils.tsx deleted file mode 100644 index 691858163..000000000 --- a/apps/backend/src/route-handlers/utils.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { KnownErrors } from "@stackframe/stack-shared"; -import { UsersCrud } from "@stackframe/stack-shared/dist/interface/crud/users"; - -export function getIdFromUserIdOrMe(userId: string, user: UsersCrud['Server']['Read'] | undefined): string; -export function getIdFromUserIdOrMe(userId: string | undefined, user: UsersCrud['Server']['Read'] | undefined): string | undefined; -export function getIdFromUserIdOrMe(userId: string | undefined, user: UsersCrud['Server']['Read'] | undefined): string | undefined { - if (userId === "me") { - if (!user) { - throw new KnownErrors.CannotGetOwnUserWithoutUser(); - } - return user.id; - } - - return userId; -} \ No newline at end of file diff --git a/apps/e2e/tests/backend/backend-helpers.ts b/apps/e2e/tests/backend/backend-helpers.ts index a35496a6a..e88b4fa3e 100644 --- a/apps/e2e/tests/backend/backend-helpers.ts +++ b/apps/e2e/tests/backend/backend-helpers.ts @@ -776,11 +776,12 @@ export namespace Project { export namespace Team { export async function create(options: { accessType?: "client" | "server" } = {}, body?: any) { - const response = await niceBackendFetch("/api/v1/teams?add_current_user=true", { + const response = await niceBackendFetch("/api/v1/teams", { accessType: options.accessType ?? "server", method: "POST", body: { display_name: body?.display_name || 'New Team', + creator_user_id: 'me', ...body, }, }); diff --git a/apps/e2e/tests/backend/endpoints/api/v1/team-memberships.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/team-memberships.test.ts index e00a187b8..ad7856869 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/team-memberships.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/team-memberships.test.ts @@ -306,3 +306,122 @@ it("removes user from team on the client", async ({ expect }) => { } `); }); + +it("creates a team and not add the current user as a member on the client", async ({ expect }) => { + const { userId } = await Auth.Otp.signIn(); + const response = await niceBackendFetch("/api/v1/teams", { + accessType: "client", + method: "POST", + body: { + display_name: "My Team", + }, + }); + expect(response).toMatchInlineSnapshot(` + NiceResponse { + "status": 201, + "body": { + "client_metadata": null, + "client_read_only_metadata": null, + "display_name": "My Team", + "id": "", + "profile_image_url": null, + }, + "headers": Headers {