From 9812666c5f2b11c4d88577ccd455fdd4515477ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0o=C5=A1i=C4=87?= Date: Fri, 23 Feb 2024 12:37:12 +0100 Subject: [PATCH 1/3] Fix defineUserSignupFields example in migration instructions (#1802) --- web/docs/migrate-from-0-11-to-0-12.md | 41 +++++++++++---------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/web/docs/migrate-from-0-11-to-0-12.md b/web/docs/migrate-from-0-11-to-0-12.md index a5cd54d811..6a019ed841 100644 --- a/web/docs/migrate-from-0-11-to-0-12.md +++ b/web/docs/migrate-from-0-11-to-0-12.md @@ -418,14 +418,14 @@ You can follow these steps to migrate to the new auth system (assuming you alrea // highlight-next-line export const fields = defineUserSignupFields({ address: async (data) => { - const address = data.address + const address = data.address; if (typeof address !== 'string') { - throw new Error('Address is required') + throw new Error('Address is required'); } if (address.length < 5) { - throw new Error('Address must be at least 5 characters long') + throw new Error('Address must be at least 5 characters long'); } - return address + return address; }, }) ``` @@ -504,16 +504,17 @@ You can follow these steps to migrate to the new auth system (assuming you alrea // highlight-start export const fields = defineUserSignupFields({ displayName: async (data) => { - if (!data.profile || !data.profile.displayName) { - throw new Error('Display name is not available') - } - return data.profile.displayName + const profile: any = data.profile; + if (!profile?.displayName) { throw new Error('Display name is not available'); } + return profile.displayName; }, }) // highlight-end ``` - Read more about the `userSignupFields` function [here](/auth/overview.md#1-defining-extra-fields). + If you want to properly type the `profile` object, we recommend you use a validation library like Zod to define the shape of the `profile` object. + + Read more about this and the `defineUserSignupFields` function in the [Auth Overview - Defining Extra Fields](./auth/overview.md#1-defining-extra-fields) section. @@ -728,12 +729,7 @@ import { useState } from "react"; export function MigratePasswordPage() { const [successMessage, setSuccessMessage] = useState(null); const [errorMessage, setErrorMessage] = useState(null); - const form = useForm({ - defaultValues: { - username: "", - password: "", - }, - }); + const form = useForm(); const onSubmit = form.handleSubmit(async (data) => { try { @@ -893,8 +889,9 @@ export const migratePassword = async ({ password, username }, _context) => { throw new HttpError(400, "Something went wrong"); } - const providerData = - deserializeAndSanitizeProviderData < "username" > authIdentity.providerData; + const providerData = deserializeAndSanitizeProviderData( + authIdentity.providerData + ); try { const SP = new SecurePassword(); @@ -911,13 +908,9 @@ export const migratePassword = async ({ password, username }, _context) => { // This will hash the password using the new algorithm and update the // provider data in the database. - (await updateAuthIdentityProviderData) < - "username" > - (providerId, - providerData, - { - hashedPassword: password, - }); + await updateAuthIdentityProviderData(providerId, providerData, { + hashedPassword: password, + }); } catch (e) { throw new HttpError(400, "Something went wrong"); } From c4f1ae4cec9190cccd98b1fffe86e72c1f3fea36 Mon Sep 17 00:00:00 2001 From: Mihovil Ilakovac Date: Fri, 23 Feb 2024 13:03:43 +0100 Subject: [PATCH 2/3] Migrates Auth Overview docs to 0.12 Signed-off-by: Mihovil Ilakovac --- web/docs/auth/overview.md | 136 ++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 70 deletions(-) diff --git a/web/docs/auth/overview.md b/web/docs/auth/overview.md index 80afac1680..14c7134931 100644 --- a/web/docs/auth/overview.md +++ b/web/docs/auth/overview.md @@ -96,7 +96,7 @@ If you set it to `true`, only authenticated users can access the page. Unauthent ```wasp title="main.wasp" page MainPage { - component: import Main from "@client/pages/Main.jsx", + component: import Main from "@src/pages/Main.jsx", authRequired: true } ``` @@ -106,7 +106,7 @@ page MainPage { ```wasp title="main.wasp" page MainPage { - component: import Main from "@client/pages/Main.tsx", + component: import Main from "@src/pages/Main.tsx", authRequired: true } ``` @@ -127,8 +127,8 @@ We provide an action for logging out the user. Here's how you can use it: -```jsx title="client/components/LogoutButton.jsx" -import logout from '@wasp/auth/logout' +```jsx title="src/components/LogoutButton.jsx" +import { logout } from 'wasp/client/auth' const LogoutButton = () => { return @@ -138,8 +138,8 @@ const LogoutButton = () => { -```tsx title="client/components/LogoutButton.tsx" -import logout from '@wasp/auth/logout' +```tsx title="src/components/LogoutButton.tsx" +import { logout } from 'wasp/client/auth' const LogoutButton = () => { return @@ -197,14 +197,14 @@ If the page's declaration sets `authRequired` to `true`, the page's React compon // ... page AccountPage { - component: import Account from "@client/pages/Account.jsx", + component: import Account from "@src/pages/Account.jsx", authRequired: true } ``` -```jsx title="client/pages/Account.jsx" +```jsx title="src/pages/Account.jsx" import Button from './Button' -import logout from '@wasp/auth/logout' +import { logout } from 'wasp/client/auth' const AccountPage = ({ user }) => { return ( @@ -225,17 +225,17 @@ export default AccountPage // ... page AccountPage { - component: import Account from "@client/pages/Account.tsx", + component: import Account from "@src/pages/Account.tsx", authRequired: true } ``` -```tsx title="client/pages/Account.tsx" -import { User as AuthenticatedUser } from '@wasp/auth/types' +```tsx title="src/pages/Account.tsx" +import { type AuthUser } from 'wasp/auth' import Button from './Button' -import logout from '@wasp/auth/logout' +import { logout } from 'wasp/client/auth' -const AccountPage = ({ user }: { user: AuthenticatedUser }) => { +const AccountPage = ({ user }: { user: AuthUser }) => { return (
@@ -259,10 +259,9 @@ This hook is a thin wrapper over Wasp's `useQuery` hook and returns data in the -```jsx title="src/client/pages/MainPage.jsx" -import useAuth from '@wasp/auth/useAuth' +```jsx title="src/pages/MainPage.jsx" +import { useAuth, logout } from 'wasp/client/auth' import { Link } from 'react-router-dom' -import logout from '@wasp/auth/logout' import Todo from '../Todo' export function Main() { @@ -289,10 +288,9 @@ export function Main() { -```tsx title="src/client/pages/MainPage.tsx" -import useAuth from '@wasp/auth/useAuth' +```tsx title="src/pages/MainPage.tsx" +import { useAuth, logout } from 'wasp/client/auth' import { Link } from 'react-router-dom' -import logout from '@wasp/auth/logout' import Todo from '../Todo' export function Main() { @@ -331,8 +329,8 @@ When authentication is enabled, all [queries and actions](../data-model/operatio -```js title="src/server/actions.js" -import HttpError from '@wasp/core/HttpError.js' +```js title="src/actions.js" +import { HttpError } from 'wasp/server' export const createTask = async (task, context) => { if (!context.user) { @@ -354,10 +352,10 @@ export const createTask = async (task, context) => { -```ts title="src/server/actions.ts" -import type { Task } from '@wasp/entities' -import type { CreateTask } from '@wasp/actions/types' -import HttpError from '@wasp/core/HttpError.js' +```ts title="src/actions.ts" +import { type Task } from 'wasp/entities' +import { type CreateTask } from 'wasp/server/operations' +import { HttpError } from 'wasp/server' type CreateTaskPayload = Pick @@ -404,20 +402,20 @@ If you are saving a user's password in the database, you should **never** save i // ... action updatePassword { - fn: import { updatePassword } from "@server/auth.js", + fn: import { updatePassword } from "@src/auth", } ``` -```js title="src/server/actions.js" +```js title="src/auth.js" import { createProviderId, findAuthIdentity, updateAuthIdentityProviderData, deserializeAndSanitizeProviderData, -} from '@wasp/auth/utils.js'; +} from 'wasp/server/auth'; export const updatePassword = async (args, context) => { const providerId = createProviderId('email', args.email) @@ -438,14 +436,14 @@ export const updatePassword = async (args, context) => { -```ts title="src/server/actions.ts" +```ts title="src/auth.ts" import { createProviderId, findAuthIdentity, updateAuthIdentityProviderData, deserializeAndSanitizeProviderData, -} from '@wasp/auth/utils.js'; -import type { UpdatePassword } from '@wasp/actions/types' +} from 'wasp/server/auth'; +import { type UpdatePassword } from 'wasp/server/operations' export const updatePassword: UpdatePassword< { email: string; password: string }, @@ -534,7 +532,7 @@ app crudTesting { userEntity: User, methods: { usernameAndPassword: { - userSignupFields: import { userSignupFields } from "@server/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup", }, }, onAuthFailedRedirectTo: "/login", @@ -547,10 +545,10 @@ entity User {=psl psl=} ``` -Then we'll define the `userSignupFields` object in the `server/auth/signup.js` file: +Then we'll define the `userSignupFields` object in the `src/auth/signup.js` file: -```ts title="server/auth/signup.js" -import { defineUserSignupFields } from '@wasp/auth/index.js' +```ts title="src/auth/signup.js" +import { defineUserSignupFields } from 'wasp/server/auth' export const userSignupFields = defineUserSignupFields({ address: async (data) => { @@ -576,7 +574,7 @@ app crudTesting { userEntity: User, methods: { usernameAndPassword: { - userSignupFields: import { userSignupFields } from "@server/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup.js", }, }, onAuthFailedRedirectTo: "/login", @@ -589,10 +587,10 @@ entity User {=psl psl=} ``` -Then we'll define the `userSignupFields` object in the `server/auth/signup.js` file: +Then we'll define the `userSignupFields` object in the `src/auth/signup.js` file: -```ts title="server/auth/signup.ts" -import { defineUserSignupFields } from '@wasp/auth/index.js' +```ts title="src/auth/signup.ts" +import { defineUserSignupFields } from 'wasp/server/auth' export const userSignupFields = defineUserSignupFields({ address: async (data) => { @@ -630,8 +628,8 @@ You can use any validation library you want to validate the fields. For example, -```js title="server/auth/signup.js" -import { defineUserSignupFields } from '@wasp/auth/index.js' +```js title="src/auth/signup.js" +import { defineUserSignupFields } from 'wasp/server/auth' import * as z from 'zod' export const userSignupFields = defineUserSignupFields({ @@ -654,8 +652,8 @@ export const userSignupFields = defineUserSignupFields({ -```ts title="server/auth/signup.ts" -import { defineUserSignupFields } from '@wasp/auth/index.js' +```ts title="src/auth/signup.ts" +import { defineUserSignupFields } from 'wasp/server/auth' import * as z from 'zod' export const userSignupFields = defineUserSignupFields({ @@ -714,14 +712,14 @@ Inside the list, there can be either **objects** or **render functions** (you ca -```jsx title="client/SignupPage.jsx" -import { SignupForm } from '@wasp/auth/forms/Signup' +```jsx title="src/SignupPage.jsx" import { + SignupForm, FormError, FormInput, FormItemGroup, FormLabel, -} from '@wasp/auth/forms/internal/Form' +} from 'wasp/client/auth' export const SignupPage = () => { return ( @@ -764,14 +762,14 @@ export const SignupPage = () => { -```tsx title="client/SignupPage.tsx" -import { SignupForm } from '@wasp/auth/forms/Signup' +```tsx title="src/SignupPage.tsx" import { + SignupForm, FormError, FormInput, FormItemGroup, FormLabel, -} from '@wasp/auth/forms/internal/Form' +} from 'wasp/client/auth' export const SignupPage = () => { return ( @@ -826,9 +824,8 @@ Instead of passing in a list of extra fields, you can pass in a render function -```jsx title="client/SignupPage.jsx" -import { SignupForm } from '@wasp/auth/forms/Signup' -import { FormItemGroup } from '@wasp/auth/forms/internal/Form' +```jsx title="src/SignupPage.jsx" +import { SignupForm, FormItemGroup } from 'wasp/client/auth' export const SignupPage = () => { return ( @@ -851,9 +848,8 @@ export const SignupPage = () => { -```tsx title="client/SignupPage.tsx" -import { SignupForm } from '@wasp/auth/forms/Signup' -import { FormItemGroup } from '@wasp/auth/forms/internal/Form' +```tsx title="src/SignupPage.tsx" +import { SignupForm, FormItemGroup } from 'wasp/client/auth' export const SignupPage = () => { return ( @@ -980,7 +976,7 @@ app crudTesting { methods: { usernameAndPassword: { // highlight-next-line - userSignupFields: import { userSignupFields } from "@server/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup.js", }, }, onAuthFailedRedirectTo: "/login", @@ -988,10 +984,10 @@ app crudTesting { } ``` -Then we'll export the `userSignupFields` object from the `server/auth/signup.js` file: +Then we'll export the `userSignupFields` object from the `src/auth/signup.js` file: -```ts title="server/auth/signup.js" -import { defineUserSignupFields } from '@wasp/auth/index.js' +```ts title="src/auth/signup.js" +import { defineUserSignupFields } from 'wasp/server/auth' export const userSignupFields = defineUserSignupFields({ address: async (data) => { @@ -1018,7 +1014,7 @@ app crudTesting { methods: { usernameAndPassword: { // highlight-next-line - userSignupFields: import { userSignupFields } from "@server/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup.js", }, }, onAuthFailedRedirectTo: "/login", @@ -1026,10 +1022,10 @@ app crudTesting { } ``` -Then we'll export the `userSignupFields` object from the `server/auth/signup.ts` file: +Then we'll export the `userSignupFields` object from the `src/auth/signup.ts` file: -```ts title="server/auth/signup.ts" -import { defineUserSignupFields } from '@wasp/auth/index.js' +```ts title="src/auth/signup.ts" +import { defineUserSignupFields } from 'wasp/server/auth' export const userSignupFields = defineUserSignupFields({ address: async (data) => { @@ -1064,14 +1060,14 @@ To customize the `SignupForm` component, you need to pass in the `additionalFiel -```jsx title="client/SignupPage.jsx" -import { SignupForm } from '@wasp/auth/forms/Signup' +```jsx title="src/SignupPage.jsx" import { + SignupForm, FormError, FormInput, FormItemGroup, FormLabel, -} from '@wasp/auth/forms/internal/Form' +} from 'wasp/client/auth' export const SignupPage = () => { return ( @@ -1112,14 +1108,14 @@ export const SignupPage = () => { -```tsx title="client/SignupPage.tsx" -import { SignupForm } from '@wasp/auth/forms/Signup' +```tsx title="src/SignupPage.tsx" import { + SignupForm, FormError, FormInput, FormItemGroup, FormLabel, -} from '@wasp/auth/forms/internal/Form' +} from 'wasp/client/auth' export const SignupPage = () => { return ( From 49fe129adb5193ab62c7c32f48a0d5e511553aa3 Mon Sep 17 00:00:00 2001 From: Mihovil Ilakovac Date: Fri, 23 Feb 2024 13:07:28 +0100 Subject: [PATCH 3/3] Cleanup --- web/docs/auth/overview.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/web/docs/auth/overview.md b/web/docs/auth/overview.md index 14c7134931..c3666b81f4 100644 --- a/web/docs/auth/overview.md +++ b/web/docs/auth/overview.md @@ -96,7 +96,7 @@ If you set it to `true`, only authenticated users can access the page. Unauthent ```wasp title="main.wasp" page MainPage { - component: import Main from "@src/pages/Main.jsx", + component: import Main from "@src/pages/Main", authRequired: true } ``` @@ -106,7 +106,7 @@ page MainPage { ```wasp title="main.wasp" page MainPage { - component: import Main from "@src/pages/Main.tsx", + component: import Main from "@src/pages/Main", authRequired: true } ``` @@ -197,7 +197,7 @@ If the page's declaration sets `authRequired` to `true`, the page's React compon // ... page AccountPage { - component: import Account from "@src/pages/Account.jsx", + component: import Account from "@src/pages/Account", authRequired: true } ``` @@ -225,7 +225,7 @@ export default AccountPage // ... page AccountPage { - component: import Account from "@src/pages/Account.tsx", + component: import Account from "@src/pages/Account", authRequired: true } ``` @@ -411,10 +411,10 @@ action updatePassword { ```js title="src/auth.js" import { - createProviderId, - findAuthIdentity, - updateAuthIdentityProviderData, - deserializeAndSanitizeProviderData, + createProviderId, + findAuthIdentity, + updateAuthIdentityProviderData, + deserializeAndSanitizeProviderData, } from 'wasp/server/auth'; export const updatePassword = async (args, context) => { @@ -438,10 +438,10 @@ export const updatePassword = async (args, context) => { ```ts title="src/auth.ts" import { - createProviderId, - findAuthIdentity, - updateAuthIdentityProviderData, - deserializeAndSanitizeProviderData, + createProviderId, + findAuthIdentity, + updateAuthIdentityProviderData, + deserializeAndSanitizeProviderData, } from 'wasp/server/auth'; import { type UpdatePassword } from 'wasp/server/operations' @@ -574,7 +574,7 @@ app crudTesting { userEntity: User, methods: { usernameAndPassword: { - userSignupFields: import { userSignupFields } from "@src/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup", }, }, onAuthFailedRedirectTo: "/login", @@ -976,7 +976,7 @@ app crudTesting { methods: { usernameAndPassword: { // highlight-next-line - userSignupFields: import { userSignupFields } from "@src/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup", }, }, onAuthFailedRedirectTo: "/login", @@ -1014,7 +1014,7 @@ app crudTesting { methods: { usernameAndPassword: { // highlight-next-line - userSignupFields: import { userSignupFields } from "@src/auth/signup.js", + userSignupFields: import { userSignupFields } from "@src/auth/signup", }, }, onAuthFailedRedirectTo: "/login",