mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 02:42:25 +08:00
fix(server): change password with token should be public (#7855)
This commit is contained in:
@@ -7,19 +7,12 @@ import { Button } from '../../ui/button';
|
||||
import { notify } from '../../ui/notification';
|
||||
import { AuthPageContainer } from './auth-page-container';
|
||||
import { SetPassword } from './set-password';
|
||||
import type { User } from './type';
|
||||
|
||||
export const ChangePasswordPage: FC<{
|
||||
user: User;
|
||||
passwordLimits: PasswordLimitsFragment;
|
||||
onSetPassword: (password: string) => Promise<void>;
|
||||
onOpenAffine: () => void;
|
||||
}> = ({
|
||||
user: { email },
|
||||
passwordLimits,
|
||||
onSetPassword: propsOnSetPassword,
|
||||
onOpenAffine,
|
||||
}) => {
|
||||
}> = ({ passwordLimits, onSetPassword: propsOnSetPassword, onOpenAffine }) => {
|
||||
const t = useI18n();
|
||||
const [hasSetUp, setHasSetUp] = useState(false);
|
||||
|
||||
@@ -45,17 +38,12 @@ export const ChangePasswordPage: FC<{
|
||||
: t['com.affine.auth.reset.password.page.title']()
|
||||
}
|
||||
subtitle={
|
||||
hasSetUp ? (
|
||||
t['com.affine.auth.sent.reset.password.success.message']()
|
||||
) : (
|
||||
<>
|
||||
{t['com.affine.auth.page.sent.email.subtitle']({
|
||||
hasSetUp
|
||||
? t['com.affine.auth.sent.reset.password.success.message']()
|
||||
: t['com.affine.auth.page.sent.email.subtitle']({
|
||||
min: String(passwordLimits.minLength),
|
||||
max: String(passwordLimits.maxLength),
|
||||
})}
|
||||
<a href={`mailto:${email}`}>{email}</a>
|
||||
</>
|
||||
)
|
||||
})
|
||||
}
|
||||
>
|
||||
{hasSetUp ? (
|
||||
|
||||
@@ -7,19 +7,12 @@ import { Button } from '../../ui/button';
|
||||
import { notify } from '../../ui/notification';
|
||||
import { AuthPageContainer } from './auth-page-container';
|
||||
import { SetPassword } from './set-password';
|
||||
import type { User } from './type';
|
||||
|
||||
export const SetPasswordPage: FC<{
|
||||
user: User;
|
||||
passwordLimits: PasswordLimitsFragment;
|
||||
onSetPassword: (password: string) => Promise<void>;
|
||||
onOpenAffine: () => void;
|
||||
}> = ({
|
||||
user: { email },
|
||||
passwordLimits,
|
||||
onSetPassword: propsOnSetPassword,
|
||||
onOpenAffine,
|
||||
}) => {
|
||||
}> = ({ passwordLimits, onSetPassword: propsOnSetPassword, onOpenAffine }) => {
|
||||
const t = useI18n();
|
||||
const [hasSetUp, setHasSetUp] = useState(false);
|
||||
|
||||
@@ -45,17 +38,12 @@ export const SetPasswordPage: FC<{
|
||||
: t['com.affine.auth.set.password.page.title']()
|
||||
}
|
||||
subtitle={
|
||||
hasSetUp ? (
|
||||
t['com.affine.auth.sent.set.password.success.message']()
|
||||
) : (
|
||||
<>
|
||||
{t['com.affine.auth.page.sent.email.subtitle']({
|
||||
hasSetUp
|
||||
? t['com.affine.auth.sent.set.password.success.message']()
|
||||
: t['com.affine.auth.page.sent.email.subtitle']({
|
||||
min: String(passwordLimits.minLength),
|
||||
max: String(passwordLimits.maxLength),
|
||||
})}
|
||||
<a href={`mailto:${email}`}>{email}</a>
|
||||
</>
|
||||
)
|
||||
})
|
||||
}
|
||||
>
|
||||
{hasSetUp ? (
|
||||
|
||||
@@ -17,8 +17,7 @@ import {
|
||||
} from '@affine/graphql';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import type { LoaderFunction } from 'react-router-dom';
|
||||
import { redirect, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { z } from 'zod';
|
||||
@@ -39,7 +38,7 @@ const authTypeSchema = z.enum([
|
||||
'verify-email',
|
||||
]);
|
||||
|
||||
export const AuthPage = (): ReactElement | null => {
|
||||
export const Component = () => {
|
||||
const authService = useService(AuthService);
|
||||
const account = useLiveData(authService.session.account$);
|
||||
const t = useI18n();
|
||||
@@ -89,6 +88,7 @@ export const AuthPage = (): ReactElement | null => {
|
||||
async (password: string) => {
|
||||
await changePassword({
|
||||
token: searchParams.get('token') || '',
|
||||
userId: searchParams.get('userId') || '',
|
||||
newPassword: password,
|
||||
});
|
||||
},
|
||||
@@ -98,22 +98,26 @@ export const AuthPage = (): ReactElement | null => {
|
||||
jumpToIndex(RouteLogic.REPLACE);
|
||||
}, [jumpToIndex]);
|
||||
|
||||
if (!passwordLimits || !account) {
|
||||
if (!passwordLimits) {
|
||||
// TODO(@eyhn): loading UI
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (authType) {
|
||||
case 'onboarding':
|
||||
return <OnboardingPage user={account} onOpenAffine={onOpenAffine} />;
|
||||
return (
|
||||
account && <OnboardingPage user={account} onOpenAffine={onOpenAffine} />
|
||||
);
|
||||
case 'signUp': {
|
||||
return (
|
||||
<SignUpPage
|
||||
user={account}
|
||||
passwordLimits={passwordLimits}
|
||||
onSetPassword={onSetPassword}
|
||||
onOpenAffine={onOpenAffine}
|
||||
/>
|
||||
account && (
|
||||
<SignUpPage
|
||||
user={account}
|
||||
passwordLimits={passwordLimits}
|
||||
onSetPassword={onSetPassword}
|
||||
onOpenAffine={onOpenAffine}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
case 'signIn': {
|
||||
@@ -122,7 +126,6 @@ export const AuthPage = (): ReactElement | null => {
|
||||
case 'changePassword': {
|
||||
return (
|
||||
<ChangePasswordPage
|
||||
user={account}
|
||||
passwordLimits={passwordLimits}
|
||||
onSetPassword={onSetPassword}
|
||||
onOpenAffine={onOpenAffine}
|
||||
@@ -132,7 +135,6 @@ export const AuthPage = (): ReactElement | null => {
|
||||
case 'setPassword': {
|
||||
return (
|
||||
<SetPasswordPage
|
||||
user={account}
|
||||
passwordLimits={passwordLimits}
|
||||
onSetPassword={onSetPassword}
|
||||
onOpenAffine={onOpenAffine}
|
||||
@@ -198,25 +200,3 @@ export const loader: LoaderFunction = async args => {
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const Component = () => {
|
||||
const authService = useService(AuthService);
|
||||
const isRevalidating = useLiveData(authService.session.isRevalidating$);
|
||||
const loginStatus = useLiveData(authService.session.status$);
|
||||
const { jumpToExpired } = useNavigateHelper();
|
||||
|
||||
useEffect(() => {
|
||||
authService.session.revalidate();
|
||||
}, [authService]);
|
||||
|
||||
if (loginStatus === 'unauthenticated' && !isRevalidating) {
|
||||
jumpToExpired(RouteLogic.REPLACE);
|
||||
}
|
||||
|
||||
if (loginStatus === 'authenticated') {
|
||||
return <AuthPage />;
|
||||
}
|
||||
|
||||
// TODO(@eyhn): loading UI
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
mutation changePassword($token: String!, $newPassword: String!) {
|
||||
changePassword(token: $token, newPassword: $newPassword) {
|
||||
id
|
||||
}
|
||||
mutation changePassword(
|
||||
$token: String!
|
||||
$userId: String!
|
||||
$newPassword: String!
|
||||
) {
|
||||
changePassword(token: $token, userId: $userId, newPassword: $newPassword)
|
||||
}
|
||||
|
||||
@@ -121,10 +121,8 @@ export const changePasswordMutation = {
|
||||
definitionName: 'changePassword',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation changePassword($token: String!, $newPassword: String!) {
|
||||
changePassword(token: $token, newPassword: $newPassword) {
|
||||
id
|
||||
}
|
||||
mutation changePassword($token: String!, $userId: String!, $newPassword: String!) {
|
||||
changePassword(token: $token, userId: $userId, newPassword: $newPassword)
|
||||
}`,
|
||||
};
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ export enum ErrorNames {
|
||||
INVALID_OAUTH_CALLBACK_STATE = 'INVALID_OAUTH_CALLBACK_STATE',
|
||||
INVALID_PASSWORD_LENGTH = 'INVALID_PASSWORD_LENGTH',
|
||||
INVALID_RUNTIME_CONFIG_TYPE = 'INVALID_RUNTIME_CONFIG_TYPE',
|
||||
LINK_EXPIRED = 'LINK_EXPIRED',
|
||||
MAILER_SERVICE_IS_NOT_CONFIGURED = 'MAILER_SERVICE_IS_NOT_CONFIGURED',
|
||||
MEMBER_QUOTA_EXCEEDED = 'MEMBER_QUOTA_EXCEEDED',
|
||||
MISSING_OAUTH_QUERY_PARAMETER = 'MISSING_OAUTH_QUERY_PARAMETER',
|
||||
@@ -467,7 +468,7 @@ export interface Mutation {
|
||||
addWorkspaceFeature: Scalars['Int']['output'];
|
||||
cancelSubscription: UserSubscription;
|
||||
changeEmail: UserType;
|
||||
changePassword: UserType;
|
||||
changePassword: Scalars['Boolean']['output'];
|
||||
/** Cleanup sessions */
|
||||
cleanupCopilotSession: Array<Scalars['String']['output']>;
|
||||
/** Create change password url */
|
||||
@@ -557,6 +558,7 @@ export interface MutationChangeEmailArgs {
|
||||
export interface MutationChangePasswordArgs {
|
||||
newPassword: Scalars['String']['input'];
|
||||
token: Scalars['String']['input'];
|
||||
userId: InputMaybe<Scalars['String']['input']>;
|
||||
}
|
||||
|
||||
export interface MutationCleanupCopilotSessionArgs {
|
||||
@@ -1321,12 +1323,13 @@ export type CreateChangePasswordUrlMutation = {
|
||||
|
||||
export type ChangePasswordMutationVariables = Exact<{
|
||||
token: Scalars['String']['input'];
|
||||
userId: Scalars['String']['input'];
|
||||
newPassword: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type ChangePasswordMutation = {
|
||||
__typename?: 'Mutation';
|
||||
changePassword: { __typename?: 'UserType'; id: string };
|
||||
changePassword: boolean;
|
||||
};
|
||||
|
||||
export type CopilotQuotaQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
Reference in New Issue
Block a user