Skip to content
This repository was archived by the owner on Jan 4, 2024. It is now read-only.

Commit e081f26

Browse files
authored
add UUID keys support (#20)
* yay UUID support * push version to 1.1.6
1 parent f3f6dfd commit e081f26

File tree

12 files changed

+288
-12
lines changed

12 files changed

+288
-12
lines changed

Theos/Classes/Exts.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
#include <Foundation/Foundation.h>
2+
#include <Foundation/NSArray.h>
3+
#include <Foundation/NSFileManager.h>
14
#include <Foundation/NSUserDefaults.h>
25
#import <UIKit/UIKit.h>
6+
#include <objc/objc.h>
37

48
@interface UIImage (Scale)
59
+ (UIImage *)resizeImageFromImage:(UIImage *)image withSize:(CGSize)size;
@@ -16,4 +20,16 @@
1620

1721
@interface NSDataDetector (Shared)
1822
+ (NSDataDetector*)sharedInstance;
23+
@end
24+
25+
@interface NSFileManager (Batch)
26+
- (NSError*)removeItemsAtPaths:(NSArray<NSString*>*)paths withBlacklist:(NSSet<NSString*>*)blacklist;
27+
@end
28+
29+
@interface NSArray (Paths)
30+
-(NSArray<NSString*>*)arrayByPrePendingPathComponent:(NSString*)component;
31+
@end
32+
33+
@interface NSString (Paths)
34+
- (BOOL)pathPartOfPaths:(NSSet<NSString*>*)paths;
1935
@end

Theos/Classes/Exts.m

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#import "Exts.h"
2+
#include "Classes/JDESettingsManager.h"
3+
#include <Foundation/NSError.h>
4+
#include <Foundation/Foundation.h>
25
#include <UIKit/UIColor.h>
36
@implementation UIImage (Scale)
47
// Resize images by luki120 @ Theos discord
@@ -57,6 +60,45 @@ - (UIViewController *) firstAvailableUIViewController {
5760

5861
@end
5962

63+
@implementation NSFileManager (Batch)
64+
- (NSError*)removeItemsAtPaths:(NSArray<NSString*>*)paths withBlacklist:(NSSet<NSString*>*)blacklist{
65+
NSError *err = nil;
66+
for(NSString *path in paths){
67+
if([path pathPartOfPaths:blacklist] == NO){
68+
[self removeItemAtPath:path error:&err];
69+
}
70+
if(err != nil){
71+
return err;
72+
}
73+
}
74+
75+
76+
return nil;
77+
}
78+
79+
@end
80+
81+
@implementation NSArray (Paths)
82+
- (NSArray<NSString *> *)arrayByPrePendingPathComponent:(NSString *)component {
83+
NSMutableArray *arr = [NSMutableArray new];
84+
for(NSString *arrItem in self){
85+
[arr addObject:[component stringByAppendingPathComponent:arrItem]];
86+
}
87+
return arr;
88+
}
89+
90+
@end
91+
92+
@implementation NSString (Paths)
93+
- (BOOL)pathPartOfPaths:(NSSet<NSString*>*)paths{
94+
for (NSString *path in paths){
95+
if([self isEqualToString:path]){
96+
return YES;
97+
}
98+
}
99+
return NO;
100+
}
101+
@end
60102
@implementation NSDataDetector (Shared)
61103
+ (NSDataDetector *)sharedInstance {
62104
static NSDataDetector *shared = nil;
@@ -66,7 +108,5 @@ + (NSDataDetector *)sharedInstance {
66108
shared = [self dataDetectorWithTypes:NSTextCheckingTypeLink|NSTextCheckingTypePhoneNumber error:nil];
67109
});
68110
return shared;
69-
70-
}
71-
72-
@end
111+
}
112+
@end

Theos/Classes/JDESettingsManager.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ - (NSDictionary*)cellInfoForPath:(NSIndexPath*)indexPath{
114114
@"title": @"Theming",
115115
@"image": [UIImage systemImageNamed:@"scribble"]
116116
}; break;
117+
case 4:
118+
info = @{
119+
@"title": @"UUID",
120+
@"image": [UIImage systemImageNamed:@"person.crop.circle"]
121+
}; break;
117122
}
118123
}
119124
return info;

Theos/Headers/JDLOAuthHandler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface JDLOAuthHandler : NSObject
4+
+ (BOOL)clearCredentialsFromKeychain;
5+
@end

Theos/Headers/ShrinkAnimationButton.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <UIKit/UIButton.h>
2+
#import <UIKit/UIKit.h>
3+
4+
@interface ShrinkAnimationButton : UIButton
5+
- (void)didPress;
6+
@end

Theos/Headers/UICKeyChainStore.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <Foundation/Foundation.h>
2+
3+
@interface UICKeyChainStore : NSObject
4+
+ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service;
5+
+ (BOOL)removeAllItems;
6+
- (BOOL)removeAllItems;
7+
- (NSArray *)allItems;
8+
- (instancetype)initWithService:(NSString *)service;
9+
@end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#import <Foundation/Foundation.h>
2+
#import <UIKit/UIKit.h>
3+
4+
@interface WalkthroughViewController : UIPageViewController <UIPageViewControllerDelegate, UIScrollViewDelegate>
5+
- (void)didTapNext; //called when ShrinkAnimationButton is tapped
6+
- (void)showTokenAlertWithCompletion:(void (^)())completion;
7+
@end

Theos/JDEViewController.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#import "Classes/JDESettingsManager.h"
44
#import "Classes/JDEMapView.h"
55
#import "Classes/Exts.h"
6+
#import "Classes/JDELogsVC.h"
67
#import "Classes/ThemingViewController.h"
7-
8+
#import "Headers/UICKeyChainStore.h"
9+
#import "Headers/JDLOAuthHandler.h"
810

911
@interface JDEViewController : UIViewController
1012
- (void)viewDidLoad;

Theos/JDEViewController.m

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
#import "JDEViewController.h"
2-
#include <UIKit/UIColor.h>
3-
#include "Classes/ThemingViewController.h"
4-
#include <UIKit/UIImage.h>
5-
#import "Classes/JDELogsVC.h"
2+
63

74
// Private declarations; this class only.
85
@interface JDEViewController() <UITableViewDelegate, UITableViewDataSource>
@@ -94,11 +91,90 @@ - (void)openLinkForIndexPath:(NSIndexPath*)indexPath{
9491
}
9592
}
9693
}
94+
95+
- (void)wipeAppData{
96+
dispatch_async(dispatch_get_main_queue(), ^{
97+
UIAlertController *progress = [UIAlertController alertControllerWithTitle:@"WIPING DATA"
98+
message:nil
99+
preferredStyle:UIAlertControllerStyleAlert];
100+
[self presentViewController:progress animated:YES completion:nil];
101+
102+
103+
104+
NSFileManager *manager = [NSFileManager defaultManager];
105+
106+
NSSet<NSString*>* setOfDirsToClean = [NSSet setWithObjects:@"~/Documents", @"~/tmp", @"~/Library", @"~/Library/Caches", nil];
107+
108+
NSMutableSet<NSString*> *DirsToIgnore = [NSMutableSet setWithCapacity:2];
109+
for(NSString *dir in @[@"~/Library/Caches", @"~/Library/SyncedPreferences", @"~/Library/Preferences", @"~/StoreKit"]){
110+
[DirsToIgnore addObject:[dir stringByExpandingTildeInPath]];
111+
}
112+
113+
114+
for(NSString *dirToClean in setOfDirsToClean){
115+
progress.title = [NSString stringWithFormat:@"Cleaning %@", dirToClean];
116+
117+
NSError *err = nil;
118+
NSString *expandedDir = [dirToClean stringByExpandingTildeInPath];
119+
120+
NSArray<NSString*> *expandedDirContent = [[manager contentsOfDirectoryAtPath:expandedDir error:&err]
121+
arrayByPrePendingPathComponent:expandedDir];
122+
if(err != nil){
123+
progress.title = err.debugDescription;
124+
return;
125+
}
126+
127+
NSError *removeError = [manager removeItemsAtPaths:expandedDirContent withBlacklist:DirsToIgnore];
128+
if(removeError != nil){
129+
progress.title = removeError.debugDescription;
130+
return;
131+
}
132+
}
133+
134+
progress.title = @"Cleaning Preferences";
135+
NSError *prefsError = nil;
136+
NSString *expandedPrefsDir = [@"~/Library/Preferences" stringByExpandingTildeInPath];
137+
NSArray<NSString*> *prefsArr = [[manager contentsOfDirectoryAtPath:expandedPrefsDir error:&prefsError]
138+
arrayByPrePendingPathComponent:expandedPrefsDir];
139+
140+
if(prefsError != nil){
141+
progress.title = prefsError.debugDescription;
142+
return;
143+
}
144+
145+
for(NSString *prefName in prefsArr){
146+
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:prefName];
147+
}
148+
149+
NSDictionary<NSString*, id> *icloudPrefs = [NSUbiquitousKeyValueStore.defaultStore dictionaryRepresentation];
150+
151+
for(NSString *key in [icloudPrefs allKeys]){
152+
[NSUbiquitousKeyValueStore.defaultStore removeObjectForKey:key];
153+
}
154+
[NSUbiquitousKeyValueStore.defaultStore synchronize];
155+
156+
157+
progress.title = @"Wiping Keychain";
158+
Class UICKeyChainStore = NSClassFromString(@"UICKeyChainStore");
159+
[UICKeyChainStore removeAllItems];
160+
161+
Class JDLOAuthHandler = NSClassFromString(@"JDLOAuthHandler");
162+
if(![JDLOAuthHandler clearCredentialsFromKeychain]){
163+
progress.title = @"Failed to wipe keychain";
164+
return;
165+
}
166+
167+
[self dismissViewControllerAnimated:progress completion:nil];
168+
exit(1);
169+
});
170+
171+
172+
}
97173
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; }
98174

99175
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
100176
if(section == 0){ return 8;}
101-
return 4;
177+
return 5;
102178
}
103179

104180
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
@@ -216,6 +292,38 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
216292
ThemingViewController *themeVC = [ThemingViewController new];
217293
[self.navigationController pushViewController:themeVC animated:YES];
218294
}
295+
else if (indexPath.row == 4) {
296+
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"fc_uuidForDevice"];
297+
if (uuid == nil){
298+
uuid = @"NOT FOUND";
299+
}
300+
301+
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
302+
message:nil
303+
preferredStyle:UIAlertControllerStyleActionSheet];
304+
305+
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
306+
style:UIAlertActionStyleCancel
307+
handler:nil];
308+
309+
UIAlertAction *wipeAccount = [UIAlertAction actionWithTitle:@"WIPE ACCOUNT"
310+
style:UIAlertActionStyleDestructive
311+
handler:^(UIAlertAction *action){
312+
[self wipeAppData];
313+
}];
314+
315+
UIAlertAction *copyUUID = [UIAlertAction actionWithTitle:[NSString stringWithFormat:@"Copy: %@", uuid]
316+
style:UIAlertActionStyleDefault
317+
handler:^(UIAlertAction *action){
318+
UIPasteboard.generalPasteboard.string = uuid;
319+
}];
320+
321+
[alert addAction:cancelAction];
322+
[alert addAction:wipeAccount];
323+
[alert addAction:copyUUID];
324+
[self presentViewController:alert animated:YES completion:nil];
325+
326+
}
219327
else {
220328
[self openLinkForIndexPath:indexPath];
221329
}

Theos/Tweak.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#import "Headers/AppHaptic.h"
66
#import "Headers/ZSWTappableLabel.h"
77
#import <SafariServices/SafariServices.h>
8+
#import "Headers/WalkthroughViewController.h"
9+
#import "Headers/ShrinkAnimationButton.h"
810

911
@interface PictureFeedViewController : UIViewController
1012
@property (weak, nonatomic, readwrite) UIButton *addReactionButton;

Theos/Tweak.x

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,80 @@
405405
}
406406
%end
407407

408+
%hook WalkthroughViewController
409+
- (void)viewDidLayoutSubviews{
410+
%orig;
411+
412+
ShrinkAnimationButton *targetButton = nil;
413+
Class trgtClass = objc_getClass("Jodel.ShrinkAnimationButton");
414+
415+
for(id view in [self view].subviews){
416+
if([view isKindOfClass:[trgtClass class]]){
417+
targetButton = view;
418+
break;
419+
}
420+
}
421+
}
422+
423+
-(void)didTapNext{
424+
UIAlertController *accAlert = [UIAlertController alertControllerWithTitle:nil
425+
message:nil
426+
preferredStyle:UIAlertControllerStyleActionSheet];
427+
428+
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
429+
style:UIAlertActionStyleCancel
430+
handler:nil];
431+
432+
UIAlertAction *withToken = [UIAlertAction actionWithTitle:@"Use Token"
433+
style:UIAlertActionStyleDefault
434+
handler:^(UIAlertAction *action){
435+
[self showTokenAlertWithCompletion:^(){
436+
%orig;
437+
}];
438+
}];
439+
440+
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"Use Default"
441+
style:UIAlertActionStyleDefault
442+
handler:^(UIAlertAction *action){
443+
%orig;
444+
}];
445+
446+
[accAlert addAction:cancelAction];
447+
[accAlert addAction:withToken];
448+
[accAlert addAction:defaultAction];
449+
[self presentViewController:accAlert animated:YES completion:nil];
450+
}
451+
%new
452+
- (void)showTokenAlertWithCompletion:(void (^)())completion{
453+
UIAlertController *tokenAlert = [UIAlertController alertControllerWithTitle:nil
454+
message:@"Use Token"
455+
preferredStyle:UIAlertControllerStyleAlert];
456+
457+
[tokenAlert addTextFieldWithConfigurationHandler:^(UITextField *textField){
458+
textField.placeholder = @"UUID key here";
459+
}];
460+
461+
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
462+
style:UIAlertActionStyleCancel
463+
handler:nil];
464+
465+
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok"
466+
style:UIAlertActionStyleDefault
467+
handler:^(UIAlertAction *alertAction){
468+
[[NSUserDefaults standardUserDefaults] setObject:[tokenAlert.textFields firstObject].text forKey:@"fc_uuidForDevice"];
469+
completion();
470+
}];
471+
[tokenAlert addAction:cancelAction];
472+
[tokenAlert addAction:okAction];
473+
474+
[self presentViewController:tokenAlert animated:YES completion:nil];
475+
476+
}
477+
478+
%end
479+
480+
%hook ShrinkAnimationButton
481+
%end
408482
%ctor {
409483
%init(PlaceholderTextView=objc_getClass("Jodel.PlaceholderTextView"),
410484
PictureFeedViewController=objc_getClass("Jodel.PictureFeedViewController"),
@@ -416,6 +490,8 @@
416490
MainFeedViewController=objc_getClass("Jodel.MainFeedViewController"),
417491
ImageCaptureViewController=objc_getClass("Jodel.ImageCaptureViewController"),
418492
TappableLabel=objc_getClass("Jodel.TappableLabel"),
419-
FeedCellTappableLabelDelegate=objc_getClass("Jodel.FeedCellTappableLabelDelegate"));
493+
FeedCellTappableLabelDelegate=objc_getClass("Jodel.FeedCellTappableLabelDelegate"),
494+
WalkthroughViewController=objc_getClass("Jodel.WalkthroughViewController"),
495+
ShrinkAnimationButton=objc_getClass("Jodel.ShrinkAnimationButton"));
420496
}
421497

0 commit comments

Comments
 (0)