Skip to content

Commit c30641f

Browse files
committed
Setup fixes
1 parent 4014c8a commit c30641f

14 files changed

Lines changed: 1030 additions & 229 deletions

File tree

.dart_tool/build/fcd1995bc647fb959e82ea360c6c2c9a/asset_graph.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

lib/app/layouts/chat_creator/chat_creator.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,38 @@ class ChatCreatorState extends OptimizedState<ChatCreator> {
168168
selectedContacts.add(c);
169169
try {
170170
c.iMessage.value = await backend.handleiMessageState(c.address);
171+
if (!c.iMessage.value! && !ss.settings.nonIMessageWarning.value) {
172+
await showDialog(
173+
context: Get.context!,
174+
barrierDismissible: false,
175+
builder: (BuildContext context) {
176+
return AlertDialog(
177+
title: Text(
178+
"This recipient is GREEN because they do not have iMessage or you are being rate-limited.",
179+
style: context.theme.textTheme.titleLarge,
180+
),
181+
content: Text(
182+
"${ss.settings.smsForwardingTargets.isEmpty ? 'You can start a text here, and sending it will open your default messaging app. ' : ''}Rate limits can start at 0 users for brand new accounts. The only way to resolve a rate limit is patience, trying to reconfigure or re-install to 'fix' the rate limit will result in being temporarily blocked from iMessage.",
183+
style: context.theme.textTheme.bodyLarge,
184+
),
185+
backgroundColor: context.theme.colorScheme.properSurface,
186+
actions: <Widget>[
187+
TextButton(
188+
child: Text(
189+
"Ok",
190+
style: context.theme.textTheme.bodyLarge!.copyWith(color: context.theme.colorScheme.primary),
191+
),
192+
onPressed: () async {
193+
Navigator.of(context).pop();
194+
ss.settings.nonIMessageWarning.value = true;
195+
await ss.settings.saveOne('nonIMessageWarning');
196+
},
197+
),
198+
],
199+
);
200+
},
201+
);
202+
}
171203
} catch (_) {}
172204
addressController.text = "";
173205
findExistingChat();

lib/app/layouts/setup/pages/rustpush/appleid_2fa.dart

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,23 @@ class _AppleId2FAState extends OptimizedState<AppleId2FA> {
287287
} catch (e) {
288288
if (e is AnyhowException) {
289289
if (e.message.contains("MOBILEME_TERMS_OF_SERVICE_UPDATE")) {
290-
await controller.updateAccountUi((finished) => setState(() { loading = finished; }));
290+
await controller.updateAccountUi((finished) => setState(() {
291+
loading = finished;
292+
if (!finished) {
293+
if (controller.success) {
294+
controller.pageController.nextPage(
295+
duration: const Duration(milliseconds: 300),
296+
curve: Curves.easeInOut,
297+
);
298+
} else {
299+
controller.pageController.previousPage(
300+
duration: const Duration(milliseconds: 300),
301+
curve: Curves.easeInOut,
302+
);
303+
}
304+
FocusManager.instance.primaryFocus?.unfocus();
305+
}
306+
}));
291307
}
292308
controller.updateConnectError(e.message);
293309
}

lib/app/layouts/setup/pages/rustpush/appleid_login.dart

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,15 +451,16 @@ class _AppleIdLoginState extends OptimizedState<AppleIdLogin> {
451451
loading = true;
452452
});
453453
try {
454-
var (account, result, user) = await api.tryAuth(
454+
var (account, result) = await api.tryAuth(
455455
path: pushService.statePath,
456456
conf: controller.config!,
457457
conn: controller.connection!,
458458
anisette: controller.anisette!,
459459
creds: password == null ? null : (appleId, password),
460460
);
461-
controller.currentAppleUser = user;
462461
controller.currentAppleAccount = account;
462+
controller.currentAppleUser = await api.tryIcloudLogin(path: pushService.statePath, conf: controller.config!, account: account);
463+
463464
result = await controller.updateLoginState(result);
464465

465466

@@ -498,7 +499,21 @@ class _AppleIdLoginState extends OptimizedState<AppleIdLogin> {
498499
} catch (e) {
499500
if (e is AnyhowException) {
500501
if (e.message.contains("MOBILEME_TERMS_OF_SERVICE_UPDATE")) {
501-
await controller.updateAccountUi((finished) => setState(() { loading = finished; }));
502+
await controller.updateAccountUi((finished) => setState(() {
503+
loading = finished;
504+
if (!finished) {
505+
if (!controller.success) {
506+
return;
507+
}
508+
controller.goingTo2fa = false;
509+
controller.pageController.animateToPage(
510+
controller.pageController.page!.toInt() + 2,
511+
duration: const Duration(milliseconds: 300),
512+
curve: Curves.easeInOut,
513+
);
514+
FocusManager.instance.primaryFocus?.unfocus();
515+
}
516+
}));
502517
}
503518
controller.updateConnectError(e.message);
504519
}

lib/app/layouts/setup/setup_view.dart

Lines changed: 72 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,11 @@ class SetupViewController extends StatefulController {
192192
availableIAP.value = details.productDetailsList.first.subscriptionOfferDetails?.first;
193193
}
194194

195-
void updateSucceeded(Function finish) async {
195+
void updateSucceeded(Function finish, api.UpdateAccountFinish updateFinish) async {
196196
finish(true);
197197
updateConnectError('');
198198
try {
199-
currentAppleUser = await api.doLogin(path: pushService.statePath, account: currentAppleAccount!, anisette: anisette!, osConfig: config!, cookie: "termsAccepted=true");
199+
currentAppleUser = await api.doLogin(path: pushService.statePath, account: currentAppleAccount!, osConfig: config!, finish: updateFinish);
200200
ss.settings.userName.value = await api.getUserName(state: currentAppleAccount!);
201201
await doRegister();
202202
} catch (e) {
@@ -213,80 +213,93 @@ class SetupViewController extends StatefulController {
213213
}
214214

215215
Future<void> updateAccountUi(Function finish) async {
216-
var data = await api.updateAccountHeaders(account: currentAppleAccount!);
216+
var (data, finalI) = await api.updateAccountHeaders(account: currentAppleAccount!, config: config!);
217217
var request = URLRequest(url: WebUri("https://inappwebview.dev/"));
218218

219219
double height = 400;
220220
showDialog(
221221
context: Get.context!,
222222
builder: (context) => StatefulBuilder(
223-
builder: (context, setState) {
224-
return Center(child: Container(
225-
height: height,
226-
child: InAppWebView(
227-
initialUrlRequest: request,
228-
initialData: InAppWebViewInitialData(data: data, baseUrl: WebUri("https://setup.icloud.com/setup/update_account_ui")),
229-
initialSettings: InAppWebViewSettings(
230-
useShouldInterceptAjaxRequest: true,
231-
interceptOnlyAsyncAjaxRequests: false,
232-
useShouldInterceptFetchRequest: true,
233-
),
234-
shouldInterceptAjaxRequest: (controller, request) async {
235-
var anisette = await api.getAnisetteHeaders(state: this.anisette!, config: config!);
236-
for (var header in anisette.entries) {
237-
request.headers!.setRequestHeader(header.key, header.value);
238-
}
239-
return request;
240-
},
241-
shouldInterceptFetchRequest: (controller, request) async {
242-
var anisette = await api.getAnisetteHeaders(state: this.anisette!, config: config!);
243-
request.headers ??= {};
244-
request.headers!.addAll(anisette);
245-
return request;
246-
},
247-
onWebViewCreated: (controller) {
248-
controller.addJavaScriptHandler(handlerName: 'log', callback: (args) {
249-
Logger.info("AppleAccountSetup ${args[0]}");
250-
});
251-
controller.addJavaScriptHandler(handlerName: 'cancel', callback: (args) {
252-
Get.back();
253-
});
254-
controller.addJavaScriptHandler(handlerName: 'updateSucceeded', callback: (args) {
255-
updateSucceeded(finish);
256-
Get.back();
257-
});
258-
// for ios, also hijacks macos because ios doesn't load prefpange-setupservice.js, loads ios-setupservice.js but that doesn't work
259-
controller.addJavaScriptHandler(handlerName: 'confirmWithCallback', callback: (args) {
260-
updateSucceeded(finish);
261-
Get.back();
262-
});
263-
controller.addJavaScriptHandler(handlerName: 'resizeToWindow', callback: (args) {
264-
setState(() {
265-
height = args[1];
266-
});
267-
});
268-
controller.injectJavascriptFileFromAsset(assetFilePath: "assets/scripts/AppleAccountSetup.js");
269-
},
270-
)),);
271-
})
223+
builder: (context, setState) {
224+
return Center(child: Column(
225+
mainAxisSize: MainAxisSize.min,
226+
children: [
227+
Container(
228+
height: height,
229+
child: InAppWebView(
230+
initialUrlRequest: request,
231+
initialData: InAppWebViewInitialData(data: data, baseUrl: WebUri("https://setup.icloud.com/setup/update_account_ui")),
232+
initialSettings: InAppWebViewSettings(
233+
useShouldInterceptAjaxRequest: true,
234+
interceptOnlyAsyncAjaxRequests: false,
235+
useShouldInterceptFetchRequest: true,
236+
),
237+
shouldInterceptAjaxRequest: (controller, request) async {
238+
var anisette = await api.getAnisetteHeaders(state: this.anisette!, config: config!);
239+
for (var header in anisette.entries) {
240+
request.headers!.setRequestHeader(header.key, header.value);
241+
}
242+
return request;
243+
},
244+
shouldInterceptFetchRequest: (controller, request) async {
245+
var anisette = await api.getAnisetteHeaders(state: this.anisette!, config: config!);
246+
request.headers ??= {};
247+
request.headers!.addAll(anisette);
248+
return request;
249+
},
250+
onWebViewCreated: (controller) {
251+
controller.addJavaScriptHandler(handlerName: 'log', callback: (args) {
252+
Logger.info("AppleAccountSetup ${args[0]}");
253+
});
254+
controller.addJavaScriptHandler(handlerName: 'cancel', callback: (args) {
255+
Get.back();
256+
});
257+
controller.addJavaScriptHandler(handlerName: 'updateSucceeded', callback: (args) {
258+
updateSucceeded(finish, finalI);
259+
Get.back();
260+
});
261+
// for ios, also hijacks macos because ios doesn't load prefpange-setupservice.js, loads ios-setupservice.js but that doesn't work
262+
controller.addJavaScriptHandler(handlerName: 'confirmWithCallback', callback: (args) {
263+
updateSucceeded(finish, finalI);
264+
Get.back();
265+
});
266+
controller.addJavaScriptHandler(handlerName: 'resizeToWindow', callback: (args) {
267+
setState(() {
268+
height = args[1];
269+
});
270+
});
271+
controller.injectJavascriptFileFromAsset(assetFilePath: "assets/scripts/AppleAccountSetup.js");
272+
},
273+
)
274+
),
275+
TextButton(
276+
onPressed: () {
277+
updateSucceeded(finish, finalI);
278+
Get.back();
279+
},
280+
child: const Text('Accept Terms'),
281+
),
282+
],
283+
));
284+
}
285+
)
272286
);
273287
}
274288

275289
Future<api.LoginState> updateLoginState(api.LoginState ret) async {
276290
if (ret is api.LoginState_NeedsLogin) {
277-
api.IdsUser? user;
278291
ArcMutexAppleAccountDefaultAnisetteProvider account;
279-
(account, ret, user) = await api.tryAuth(
292+
(account, ret) = await api.tryAuth(
280293
path: pushService.statePath,
281294
conf: config!,
282295
conn: connection!,
283296
anisette: anisette!,
284297

285298
creds: twoFaCreds
286299
);
287-
currentAppleUser = user;
288300
currentAppleAccount?.dispose();
289301
currentAppleAccount = account;
302+
currentAppleUser = await api.tryIcloudLogin(path: pushService.statePath, conf: config!, account: account);
290303
}
291304
if (ret is api.LoginState_NeedsDevice2FA) {
292305
// subscribe now to not miss the 2fa message
@@ -446,7 +459,7 @@ class SetupViewController extends StatefulController {
446459
Align(
447460
alignment: Alignment.center,
448461
child: Text(
449-
"The above message is from Apple.\nWarning: Do not contact Apple support for help with OpenBubbles. For assistance, join our Discord from our website. If you can't login on this Mac, call Apple support.\n${RustPushBBUtils.modelToUser(devInfo.name)}\nS/N: ${devInfo.serial}\nmacOS ${devInfo.osVersion}",
462+
"The above message is from Apple.\nWarning: Do not contact Apple support for help with OpenBubbles. For assistance, join our Discord from our website. If you can't login on this Apple Device, call Apple support. When clicking the contact button below, choose 'Get Started,' not 'Chat,' and then choose 'Apple Device.' Do not mention you are using OpenBubbles.\n${RustPushBBUtils.modelToUser(devInfo.name)}\nS/N: ${devInfo.serial}\nmacOS ${devInfo.osVersion}",
450463
textAlign: TextAlign.center,
451464
style: Get.textTheme.bodySmall,
452465
)
@@ -456,7 +469,7 @@ class SetupViewController extends StatefulController {
456469
actions: [
457470
if (response.action != null)
458471
TextButton(
459-
onPressed: () => launchUrl(Uri.parse(response.action!.url), mode: LaunchMode.externalApplication),
472+
onPressed: () => launchUrl(Uri.parse("https://apple.co/IMFT-mac"), mode: LaunchMode.externalApplication),
460473
child: Text(response.action!.button, style: context.theme.textTheme.bodyLarge!.copyWith(color: context.theme.colorScheme.primary))),
461474
TextButton(
462475
onPressed: () => Get.back(),
@@ -725,7 +738,7 @@ class SetupViewController extends StatefulController {
725738
if (status.data.toString().contains("No device available!")) {
726739
Timer(const Duration(milliseconds: 100), () => pushService.offerHostedRefund(false));
727740
}
728-
throw Exception("Failed to swap ${status.statusCode}");
741+
throw Exception("Failed to swap ${status.statusCode} ${status.data.toString()}");
729742
}
730743

731744
var newTicket = status.data["new_ticket"];
@@ -1262,4 +1275,4 @@ class _ErrorTextState extends CustomState<ErrorText, String, SetupViewController
12621275
],
12631276
);
12641277
}
1265-
}
1278+
}

lib/database/global/settings.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ class Settings {
202202
final RxList<String> smsRoutingTargets = <String>[].obs;
203203
final RxMap<String, String> smsForwardingTargets = <String, String>{}.obs;
204204
final RxBool warnedTextChats = false.obs;
205+
final RxBool nonIMessageWarning = false.obs;
205206
final RxBool isTester = false.obs;
206207

207208
final RxBool enableShareZen = false.obs;
@@ -436,6 +437,7 @@ class Settings {
436437
'lastLocation': lastLocation,
437438
'enableShareZen': enableShareZen.value,
438439
'warnedTextChats': warnedTextChats.value,
440+
'nonIMessageWarning': nonIMessageWarning.value,
439441
'zenModeAware': zenModeAware.value,
440442
'isTester': isTester.value,
441443
'cloudSyncingEnabled': cloudSyncingEnabled.value,
@@ -613,6 +615,7 @@ class Settings {
613615
ss.settings.smsForwardingTargets.value = map['smsIncomingTargets'] ?? {};
614616
ss.settings.enableShareZen.value = map['enableShareZen'] ?? false;
615617
ss.settings.warnedTextChats.value = map['warnedTextChats'] ?? false;
618+
ss.settings.nonIMessageWarning.value = map['nonIMessageWarning'] ?? false;
616619
ss.settings.zenModeAware.value = map['zenModeAware'] ?? false;
617620
ss.settings.smsRoutingTargets.value = (map['smsForwardingTargets']?.runtimeType == String ? jsonDecode(map['smsForwardingTargets']) as List : []).cast<String>();
618621
ss.settings.developerMode.value = (map['developerMode']?.runtimeType == String ? jsonDecode(map['developerMode']) as List : []).cast<String>();
@@ -788,6 +791,7 @@ class Settings {
788791
s.smsForwardingTargets.value = map['smsIncomingTargets'] is String ? jsonDecode(map['smsIncomingTargets']).cast<String, String>() : <String, String>{};
789792
s.enableShareZen.value = map['enableShareZen'] ?? false;
790793
s.warnedTextChats.value = map['warnedTextChats'] ?? false;
794+
s.nonIMessageWarning.value = map['nonIMessageWarning'] ?? false;
791795
s.zenModeAware.value = map['zenModeAware'] ?? false;
792796
s.smsRoutingTargets.value = (map['smsForwardingTargets']?.runtimeType == String ? jsonDecode(map['smsForwardingTargets']) as List : []).cast<String>();
793797
s.developerMode.value = (map['developerMode']?.runtimeType == String ? jsonDecode(map['developerMode']) as List : []).cast<String>();

0 commit comments

Comments
 (0)