Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create forget and reset password page #28

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,61 @@ class AuthRepositoryImpl implements AuthRepository {
'Logout failed with status code: ${response.statusCode}');
}
}

Future<void> forgetPassword(String email) async {
final url = Uri.parse('http://localhost:3000/api/auth/forget-password');
try {
final response = await client.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': email}),
);

if (response.statusCode != 200) {
// Handle error responses from the server
final responseData = jsonDecode(response.body);
final errorMessage =
responseData['message'] ?? 'Failed to send reset email';
throw ServerException(errorMessage);
}
// If statusCode is 200, assume the request was successful
} catch (error) {
// Re-throw network or parsing errors as custom exceptions
throw Exception('An error occurred. Please try again.');
}
}

Future<String> resetPasswordVerify(String token) async {
final url = Uri.parse(
'http://localhost:3000/api/auth/reset-password-verify/$token');
final response = await client.get(
url,
headers: {'Content-Type': 'application/json'},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return data['message'];
} else {
throw ServerException(
'Password reset verification failed with status code: ${response.statusCode}');
}
}

Future<String> resetPassword(String token, String newPassword) async {
final url =
Uri.parse('http://localhost:3000/api/auth/reset-password/$token');
final response = await client.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'password': newPassword}),
);

if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return data['message'];
} else {
throw ServerException(
'Password reset failed with status code: ${response.statusCode}');
}
}
}
3 changes: 3 additions & 0 deletions domain/lib/repositories_abstract/auth_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ abstract class AuthRepository {
Future<User> signup(String username, String email, String password);
Future<String> login(String username, String password);
Future<void> logout();
Future<void> forgetPassword(String email);
Future<String> resetPasswordVerify(String token);
Future<String> resetPassword(String token, String newPassword);
}
12 changes: 12 additions & 0 deletions domain/lib/usecases/auth_usecase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,16 @@ class AuthUseCase {
final token = await tokenProvider.getToken();
return token != null;
}

Future<void> forgetPassword(String email) async {
return await repository.forgetPassword(email);
}

Future<String> resetPasswordVerify(String token) async {
return await repository.resetPasswordVerify(token);
}

Future<String> resetPassword(String token, String newPassword) async {
return await repository.resetPassword(token, newPassword);
}
}
17 changes: 17 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
"ignore": [
"firebase.json",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{
"source": "/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
]
}
}
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ PODS:
- FlutterMacOS
- amplify_secure_storage (0.0.1):
- Flutter
- app_links (0.0.2):
- Flutter
- app_tracking_transparency (0.0.1):
- Flutter
- device_info (0.0.1):
Expand Down Expand Up @@ -37,6 +39,7 @@ PODS:
DEPENDENCIES:
- amplify_auth_cognito (from `.symlinks/plugins/amplify_auth_cognito/darwin`)
- amplify_secure_storage (from `.symlinks/plugins/amplify_secure_storage/ios`)
- app_links (from `.symlinks/plugins/app_links/ios`)
- app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`)
- device_info (from `.symlinks/plugins/device_info/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
Expand All @@ -60,6 +63,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/amplify_auth_cognito/darwin"
amplify_secure_storage:
:path: ".symlinks/plugins/amplify_secure_storage/ios"
app_links:
:path: ".symlinks/plugins/app_links/ios"
app_tracking_transparency:
:path: ".symlinks/plugins/app_tracking_transparency/ios"
device_info:
Expand Down Expand Up @@ -90,6 +95,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
amplify_auth_cognito: 76b5a54f05f66f69966b468b8121a0dd33a32c70
amplify_secure_storage: be403397a8ba39f5e0f2a05303b3ca03b53b9ee9
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
app_tracking_transparency: e169b653478da7bb15a6c61209015378ca73e375
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
Expand Down
5 changes: 5 additions & 0 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
99A3D7612CD6FBC600B93DAF /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
D51570C31D4B8C71E4A0A233 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
F0101E625D9607551D7077EF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -112,6 +113,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
99A3D7612CD6FBC600B93DAF /* Runner.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
Expand Down Expand Up @@ -357,6 +359,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2410201826;
Expand Down Expand Up @@ -490,6 +493,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2410201826;
Expand Down Expand Up @@ -517,6 +521,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2410201826;
Expand Down
11 changes: 11 additions & 0 deletions ios/Runner/Runner.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:compositesai.com</string>
<string>webcredentials:compositesai.com</string>
</array>
</dict>
</plist>
6 changes: 5 additions & 1 deletion lib/injection_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:data/data_sources/authenticated_http_client.dart';
import 'package:data/data_sources/function_tools_data_source.dart';
import 'package:data/data_sources/open_ai_data_source.dart';
import 'package:data/providers/token_provider_impl.dart';
import 'package:data/repositories/auth_repository.dart';
import 'package:data/repositories/auth_repository_impl.dart';
import 'package:data/repositories/chat_repository_impl.dart';
import 'package:data/repositories/chat_session_repository_imp.dart';
import 'package:data/repositories/user_repository.dart';
Expand All @@ -17,7 +17,9 @@ import 'package:get_it/get_it.dart';
import 'package:http/http.dart' as http;
import 'package:swiftcomp/presentation/settings/providers/feature_flag_provider.dart';
import 'package:swiftcomp/presentation/settings/viewModels/feature_flag_view_model.dart';
import 'package:swiftcomp/presentation/settings/viewModels/forget_password_view_model.dart';
import 'package:swiftcomp/presentation/settings/viewModels/login_view_model.dart';
import 'package:swiftcomp/presentation/settings/viewModels/reset_password_view_model.dart';
import 'package:swiftcomp/presentation/settings/viewModels/settings_view_model.dart';
import 'package:swiftcomp/presentation/settings/viewModels/signup_view_model.dart';
import 'package:swiftcomp/presentation/settings/viewModels/user_profile_view_model.dart';
Expand All @@ -42,6 +44,8 @@ void initInjection() {
() => FeatureFlagViewModel(featureFlagProvider: sl()));
sl.registerFactory<UserProfileViewModel>(() =>
UserProfileViewModel(authUseCase: sl(), userUseCase: sl()));
sl.registerFactory<ResetPasswordViewModel>(() => ResetPasswordViewModel(authUseCase: sl()));
sl.registerFactory<ForgetPasswordViewModel>(() => ForgetPasswordViewModel(authUseCase: sl()));

// Providers
sl.registerLazySingleton<TokenProvider>(() => TokenProviderImpl());
Expand Down
4 changes: 3 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'dart:async';

import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
Expand Down Expand Up @@ -59,7 +62,6 @@ class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();

_configureAmplify();
}

Expand Down
61 changes: 60 additions & 1 deletion lib/presentation/bottom_navigator.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:app_links/app_links.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:swiftcomp/presentation/chat/viewModels/chat_view_model.dart';
import 'package:swiftcomp/presentation/settings/providers/feature_flag_provider.dart';
import 'package:swiftcomp/presentation/settings/views/reset_password_page.dart';
import 'package:swiftcomp/presentation/tools/page/tool_page.dart';

import 'chat/views/chat_screen.dart';
Expand All @@ -15,6 +18,7 @@ class BottomNavigator extends StatefulWidget {
}

class _BottomNavigatorState extends State<BottomNavigator> {
late final AppLinks _appLinks;
final PageController _controller = PageController(
initialPage: 0,
);
Expand All @@ -26,6 +30,11 @@ class _BottomNavigatorState extends State<BottomNavigator> {
@override
void initState() {
super.initState();
if (kIsWeb) {
_handleWebLink();
} else {
_setupAppLinks();
}
}

@override
Expand All @@ -41,7 +50,11 @@ class _BottomNavigatorState extends State<BottomNavigator> {
body: PageView(
controller: _controller,
physics: const NeverScrollableScrollPhysics(),
children: [if (isChatEnabled) ChatScreen(), ToolPage(), SettingsPage()],
children: [
if (isChatEnabled) ChatScreen(),
ToolPage(),
SettingsPage()
],
),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Color.fromRGBO(51, 66, 78, 1),
Expand Down Expand Up @@ -78,4 +91,50 @@ class _BottomNavigatorState extends State<BottomNavigator> {
),
label: title);
}

void _handleWebLink() {
final uri = Uri.base;
final pathSegments = uri.pathSegments;
if (uri.host == 'compositesai.com' || uri.host == 'localhost') {
if (uri.pathSegments.isNotEmpty && pathSegments[0] == 'reset-password') {
final token = pathSegments[1];
WidgetsBinding.instance.addPostFrameCallback((_) {
_navigateToResetPasswordPage(token);
});
}
}
}

void _setupAppLinks() async {
_appLinks = AppLinks();

_appLinks.getInitialLink().then((uri) {
if (uri != null) {
print(uri);
}
});

_appLinks.uriLinkStream.listen((uri) {
print(uri);
final token =
uri.pathSegments.length > 1 && uri.pathSegments[0] == 'reset-password'
? uri.pathSegments[1]
: uri.queryParameters['token'];
print(token);
if (token != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_navigateToResetPasswordPage(token);
});
}
});
}

void _navigateToResetPasswordPage(String token) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResetPasswordPage(token: token),
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import 'package:swiftcomp/presentation/settings/login/login_button.dart';
import 'package:swiftcomp/presentation/settings/login/login_input.dart';
import 'package:swiftcomp/util/string_util.dart';

class ForgetPasswordPage extends StatefulWidget {
const ForgetPasswordPage({Key? key}) : super(key: key);
class ForgetPasswordPageOld extends StatefulWidget {
const ForgetPasswordPageOld({Key? key}) : super(key: key);

@override
_ForgetPasswordPageState createState() => _ForgetPasswordPageState();
_ForgetPasswordPageOldState createState() => _ForgetPasswordPageOldState();
}

class _ForgetPasswordPageState extends State<ForgetPasswordPage> {
class _ForgetPasswordPageOldState extends State<ForgetPasswordPageOld> {
bool confirmEnable = false;
bool resetEnable = false;
String? email;
Expand Down
4 changes: 2 additions & 2 deletions lib/presentation/settings/login/old_login_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:swiftcomp/presentation/settings/login/registration_page.dart';
import 'package:swiftcomp/util/string_util.dart';

import 'email_confimation_screen.dart';
import 'forget_password_page.dart';
import 'forget_password_page_old.dart';

class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
Expand Down Expand Up @@ -80,7 +80,7 @@ class _LoginPageState extends State<LoginPage> {
enable: true,
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => const ForgetPasswordPage()));
MaterialPageRoute(builder: (context) => const ForgetPasswordPageOld()));
},
)),
],
Expand Down
Loading
Loading