feat(mobile): glömt-lösenord via Firebase + upprepa-lösenord-fält (POLISH-2)
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Text } from "react-native";
|
import { Text } from "react-native";
|
||||||
import { Link } from "expo-router";
|
import { Link } from "expo-router";
|
||||||
import { api } from "@/lib/api";
|
import { firebaseAuthProvider } from "@/lib/auth-provider/firebase";
|
||||||
import { t } from "@/lib/i18n";
|
import { t } from "@/lib/i18n";
|
||||||
import { Body, Button, Input, Screen, Spacer, Title } from "@/components/ui";
|
import { Body, Button, Input, Screen, Spacer, Title } from "@/components/ui";
|
||||||
import { colors, spacing } from "@/lib/theme";
|
import { colors, spacing } from "@/lib/theme";
|
||||||
@@ -21,7 +21,7 @@ export default function ForgotPasswordScreen() {
|
|||||||
setBusy(true);
|
setBusy(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
try {
|
try {
|
||||||
await api("/v1/auth/forgot-password", { method: "POST", body: { email } });
|
await firebaseAuthProvider.sendPasswordReset(email.trim()).catch(() => {});
|
||||||
setSent(true);
|
setSent(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err instanceof Error ? err.message : t("common.error"));
|
setError(err instanceof Error ? err.message : t("common.error"));
|
||||||
|
|||||||
@@ -22,10 +22,19 @@ export default function RegisterScreen() {
|
|||||||
const [displayName, setDisplayName] = useState("");
|
const [displayName, setDisplayName] = useState("");
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
|
const [confirmPassword, setConfirmPassword] = useState("");
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
|
if (password.length < 8) {
|
||||||
|
setError("Lösenordet måste vara minst 8 tecken.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (password !== confirmPassword) {
|
||||||
|
setError("Lösenorden matchar inte.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
try {
|
try {
|
||||||
@@ -97,11 +106,17 @@ export default function RegisterScreen() {
|
|||||||
onChangeText={setEmail}
|
onChangeText={setEmail}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder={`${t("auth.password")} (minst 10 tecken)`}
|
placeholder={`${t("auth.password")} (minst 8 tecken)`}
|
||||||
secureTextEntry
|
secureTextEntry
|
||||||
value={password}
|
value={password}
|
||||||
onChangeText={setPassword}
|
onChangeText={setPassword}
|
||||||
/>
|
/>
|
||||||
|
<Input
|
||||||
|
placeholder="Upprepa lösenord"
|
||||||
|
secureTextEntry
|
||||||
|
value={confirmPassword}
|
||||||
|
onChangeText={setConfirmPassword}
|
||||||
|
/>
|
||||||
{error && <Text style={{ color: colors.danger }}>{error}</Text>}
|
{error && <Text style={{ color: colors.danger }}>{error}</Text>}
|
||||||
<Button label={t("auth.register")} onPress={() => void submit()} loading={busy} />
|
<Button label={t("auth.register")} onPress={() => void submit()} loading={busy} />
|
||||||
<Spacer size={spacing.sm} />
|
<Spacer size={spacing.sm} />
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
signInWithEmailAndPassword,
|
signInWithEmailAndPassword,
|
||||||
createUserWithEmailAndPassword,
|
createUserWithEmailAndPassword,
|
||||||
signOut as fbSignOut,
|
signOut as fbSignOut,
|
||||||
|
sendPasswordResetEmail,
|
||||||
type Auth,
|
type Auth,
|
||||||
type User,
|
type User,
|
||||||
type Persistence,
|
type Persistence,
|
||||||
@@ -74,6 +75,9 @@ export const firebaseAuthProvider: AuthProvider = {
|
|||||||
async signOut() {
|
async signOut() {
|
||||||
await fbSignOut(auth);
|
await fbSignOut(auth);
|
||||||
},
|
},
|
||||||
|
async sendPasswordReset(email) {
|
||||||
|
await sendPasswordResetEmail(auth, email);
|
||||||
|
},
|
||||||
currentUser() {
|
currentUser() {
|
||||||
return toAuthUser(auth.currentUser);
|
return toAuthUser(auth.currentUser);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export interface AuthProvider {
|
|||||||
signInWithGoogle(): Promise<AuthUser>;
|
signInWithGoogle(): Promise<AuthUser>;
|
||||||
signInWithApple(): Promise<AuthUser>;
|
signInWithApple(): Promise<AuthUser>;
|
||||||
signOut(): Promise<void>;
|
signOut(): Promise<void>;
|
||||||
|
/** Skickar återställningsmejl för lösenord (leverantören sköter mejlet). */
|
||||||
|
sendPasswordReset(email: string): Promise<void>;
|
||||||
/** Nuvarande inloggade användare, eller null. Synkront ögonblicksvärde. */
|
/** Nuvarande inloggade användare, eller null. Synkront ögonblicksvärde. */
|
||||||
currentUser(): AuthUser | null;
|
currentUser(): AuthUser | null;
|
||||||
/** Prenumererar på inloggningsändringar. Returnerar avregistrering. */
|
/** Prenumererar på inloggningsändringar. Returnerar avregistrering. */
|
||||||
|
|||||||
Reference in New Issue
Block a user