29
29
#import < Base32/MF_Base32Additions.h>
30
30
31
31
32
+ typedef enum : NSUInteger {
33
+ OTPTokenEntrySectionBasic,
34
+ OTPTokenEntrySectionAdvanced,
35
+ OTPNumberOfTokenEntrySections,
36
+ } OTPTokenEntrySection;
37
+
38
+ typedef enum : NSUInteger {
39
+ OTPTokenEntryBasicRowType,
40
+ OTPTokenEntryBasicRowIssuer,
41
+ OTPTokenEntryBasicRowName,
42
+ OTPTokenEntryBasicRowSecret,
43
+ OTPNumberOfTokenEntryBasicRows,
44
+ } OTPTokenEntryBasicRow;
45
+
46
+ typedef enum : NSUInteger {
47
+ OTPTokenEntryAdvancedRowDigits,
48
+ OTPTokenEntryAdvancedRowAlgorithm,
49
+ OTPNumberOfTokenEntryAdvancedRows,
50
+ } OTPTokenEntryAdvancedRow;
51
+
52
+ typedef enum : NSUInteger {
53
+ OTPTokenTypeIndexTimer,
54
+ OTPTokenTypeIndexCounter,
55
+ } OTPTokenTypeIndex;
56
+
57
+ typedef enum : NSUInteger {
58
+ OTPTokenDigitsIndex6,
59
+ OTPTokenDigitsIndex7,
60
+ OTPTokenDigitsIndex8,
61
+ } OTPTokenDigitsIndex;
62
+
63
+ typedef enum : NSUInteger {
64
+ OTPTokenAlgorithmIndexSHA1,
65
+ OTPTokenAlgorithmIndexSHA256,
66
+ OTPTokenAlgorithmIndexSHA512,
67
+ } OTPTokenAlgorithmIndex;
68
+
69
+
32
70
@interface OTPTokenEntryViewController ()
33
71
<UITextFieldDelegate>
34
72
@@ -39,11 +77,20 @@ @interface OTPTokenEntryViewController ()
39
77
@property (nonatomic , strong ) OTPTextFieldCell *accountNameCell;
40
78
@property (nonatomic , strong ) OTPTextFieldCell *secretKeyCell;
41
79
80
+ @property (nonatomic ) BOOL showsAdvancedOptions;
81
+ @property (nonatomic , strong ) OTPSegmentedControlCell *digitCountCell;
82
+ @property (nonatomic , strong ) OTPSegmentedControlCell *algorithmCell;
83
+
42
84
@end
43
85
44
86
45
87
@implementation OTPTokenEntryViewController
46
88
89
+ - (instancetype )init
90
+ {
91
+ return [super initWithStyle: UITableViewStyleGrouped];
92
+ }
93
+
47
94
- (void )viewDidLoad
48
95
{
49
96
[super viewDidLoad ];
@@ -79,12 +126,36 @@ - (void)createToken
79
126
NSData *secret = [NSData dataWithBase32String: self .secretKeyCell.textField.text];
80
127
81
128
if (secret.length ) {
82
- OTPTokenType tokenType = (self.tokenTypeCell .segmentedControl .selectedSegmentIndex == 0 ) ? OTPTokenTypeTimer : OTPTokenTypeCounter;
129
+ OTPTokenType tokenType = (self.tokenTypeCell .segmentedControl .selectedSegmentIndex == OTPTokenTypeIndexTimer ) ? OTPTokenTypeTimer : OTPTokenTypeCounter;
83
130
OTPToken *token = [OTPToken tokenWithType: tokenType
84
131
secret: secret
85
132
name: self .accountNameCell.textField.text
86
133
issuer: self .issuerCell.textField.text];
87
134
135
+ switch (self.digitCountCell .segmentedControl .selectedSegmentIndex ) {
136
+ case OTPTokenDigitsIndex6:
137
+ token.digits = 6 ;
138
+ break ;
139
+ case OTPTokenDigitsIndex7:
140
+ token.digits = 7 ;
141
+ break ;
142
+ case OTPTokenDigitsIndex8:
143
+ token.digits = 8 ;
144
+ break ;
145
+ }
146
+
147
+ switch (self.algorithmCell .segmentedControl .selectedSegmentIndex ) {
148
+ case OTPTokenAlgorithmIndexSHA1:
149
+ token.algorithm = OTPAlgorithmSHA1;
150
+ break ;
151
+ case OTPTokenAlgorithmIndexSHA256:
152
+ token.algorithm = OTPAlgorithmSHA256;
153
+ break ;
154
+ case OTPTokenAlgorithmIndexSHA512:
155
+ token.algorithm = OTPAlgorithmSHA512;
156
+ break ;
157
+ }
158
+
88
159
if (token.password ) {
89
160
id <OTPTokenSourceDelegate> delegate = self.delegate ;
90
161
[delegate tokenSource: self didCreateToken: token];
@@ -99,37 +170,69 @@ - (void)createToken
99
170
100
171
#pragma mark - UITableViewDataSource
101
172
173
+ - (NSInteger )numberOfSectionsInTableView : (UITableView *)tableView
174
+ {
175
+ return OTPNumberOfTokenEntrySections;
176
+ }
177
+
102
178
- (NSInteger )tableView : (UITableView *)tableView numberOfRowsInSection : (NSInteger )section
103
179
{
104
- return 4 ;
180
+ switch (section) {
181
+ case OTPTokenEntrySectionBasic:
182
+ return OTPNumberOfTokenEntryBasicRows;
183
+ case OTPTokenEntrySectionAdvanced:
184
+ return self.showsAdvancedOptions ? OTPNumberOfTokenEntryAdvancedRows : 0 ;
185
+ }
186
+ return 0 ;
105
187
}
106
188
107
189
- (UITableViewCell *)tableView : (UITableView *)tableView cellForRowAtIndexPath : (NSIndexPath *)indexPath
108
190
{
109
- switch (indexPath.row ) {
110
- case 0 :
111
- return self.tokenTypeCell ;
112
- case 1 :
113
- return self.issuerCell ;
114
- case 2 :
115
- return self.accountNameCell ;
116
- case 3 :
117
- return self.secretKeyCell ;
191
+ switch (indexPath.section ) {
192
+ case OTPTokenEntrySectionBasic:
193
+ switch (indexPath.row ) {
194
+ case OTPTokenEntryBasicRowType:
195
+ return self.tokenTypeCell ;
196
+ case OTPTokenEntryBasicRowIssuer:
197
+ return self.issuerCell ;
198
+ case OTPTokenEntryBasicRowName:
199
+ return self.accountNameCell ;
200
+ case OTPTokenEntryBasicRowSecret:
201
+ return self.secretKeyCell ;
202
+ }
203
+ break ;
204
+ case OTPTokenEntrySectionAdvanced:
205
+ switch (indexPath.row ) {
206
+ case OTPTokenEntryAdvancedRowDigits:
207
+ return self.digitCountCell ;
208
+ case OTPTokenEntryAdvancedRowAlgorithm:
209
+ return self.algorithmCell ;
210
+ }
211
+ break ;
118
212
}
119
213
return nil ;
120
214
}
121
215
122
216
- (CGFloat)tableView : (UITableView *)tableView heightForRowAtIndexPath : (NSIndexPath *)indexPath
123
217
{
124
- switch (indexPath.row ) {
125
- case 0 :
126
- return 44 ;
127
- case 1 :
128
- return 74 ;
129
- case 2 :
130
- return 74 ;
131
- case 3 :
132
- return 74 ;
218
+ switch (indexPath.section ) {
219
+ case OTPTokenEntrySectionBasic:
220
+ switch (indexPath.row ) {
221
+ case OTPTokenEntryBasicRowType:
222
+ return 44 ;
223
+ case OTPTokenEntryBasicRowIssuer:
224
+ case OTPTokenEntryBasicRowName:
225
+ case OTPTokenEntryBasicRowSecret:
226
+ return 74 ;
227
+ }
228
+ break ;
229
+ case OTPTokenEntrySectionAdvanced:
230
+ switch (indexPath.row ) {
231
+ case OTPTokenEntryAdvancedRowDigits:
232
+ case OTPTokenEntryAdvancedRowAlgorithm:
233
+ return 54 ;
234
+ }
235
+ break ;
133
236
}
134
237
return 0 ;
135
238
}
@@ -140,18 +243,18 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
140
243
- (OTPSegmentedControlCell *)tokenTypeCell
141
244
{
142
245
if (!_tokenTypeCell) {
143
- _tokenTypeCell = [OTPSegmentedControlCell cellForTableView: self .tableView ];
144
- [_tokenTypeCell.segmentedControl insertSegmentWithTitle: @" Time Based" atIndex: 0 animated: NO ];
145
- [_tokenTypeCell.segmentedControl insertSegmentWithTitle: @" Counter Based" atIndex: 1 animated: NO ];
146
- _tokenTypeCell.segmentedControl .selectedSegmentIndex = 0 ;
246
+ _tokenTypeCell = [OTPSegmentedControlCell cell ];
247
+ [_tokenTypeCell.segmentedControl insertSegmentWithTitle: @" Time Based" atIndex: OTPTokenTypeIndexTimer animated: NO ];
248
+ [_tokenTypeCell.segmentedControl insertSegmentWithTitle: @" Counter Based" atIndex: OTPTokenTypeIndexCounter animated: NO ];
249
+ _tokenTypeCell.segmentedControl .selectedSegmentIndex = OTPTokenTypeIndexTimer ;
147
250
}
148
251
return _tokenTypeCell;
149
252
}
150
253
151
254
- (OTPTextFieldCell *)issuerCell
152
255
{
153
256
if (!_issuerCell) {
154
- _issuerCell = [OTPTextFieldCell cellForTableView: self .tableView ];
257
+ _issuerCell = [OTPTextFieldCell cell ];
155
258
_issuerCell.textLabel .text = @" Issuer" ;
156
259
_issuerCell.textField .placeholder = @" Some Website" ;
157
260
_issuerCell.textField .delegate = self;
@@ -163,7 +266,7 @@ - (OTPTextFieldCell *)issuerCell
163
266
- (OTPTextFieldCell *)accountNameCell
164
267
{
165
268
if (!_accountNameCell) {
166
- _accountNameCell = [OTPTextFieldCell cellForTableView: self .tableView ];
269
+ _accountNameCell = [OTPTextFieldCell cell ];
167
270
_accountNameCell.textLabel .text = @" Account Name" ;
168
271
_accountNameCell.textField .placeholder = @" user@example.com" ;
169
272
_accountNameCell.textField .delegate = self;
@@ -178,7 +281,7 @@ - (OTPTextFieldCell *)accountNameCell
178
281
- (OTPTextFieldCell *)secretKeyCell
179
282
{
180
283
if (!_secretKeyCell) {
181
- _secretKeyCell = [OTPTextFieldCell cellForTableView: self .tableView ];
284
+ _secretKeyCell = [OTPTextFieldCell cell ];
182
285
_secretKeyCell.textLabel .text = @" Secret Key" ;
183
286
_secretKeyCell.textField .placeholder = @" •••• •••• •••• ••••" ;
184
287
_secretKeyCell.textField .delegate = self;
@@ -189,6 +292,30 @@ - (OTPTextFieldCell *)secretKeyCell
189
292
return _secretKeyCell;
190
293
}
191
294
295
+ - (OTPSegmentedControlCell *)digitCountCell
296
+ {
297
+ if (!_digitCountCell) {
298
+ _digitCountCell = [OTPSegmentedControlCell cell ];
299
+ [_digitCountCell.segmentedControl insertSegmentWithTitle: @" 6 Digits" atIndex: OTPTokenDigitsIndex6 animated: NO ];
300
+ [_digitCountCell.segmentedControl insertSegmentWithTitle: @" 7 Digits" atIndex: OTPTokenDigitsIndex7 animated: NO ];
301
+ [_digitCountCell.segmentedControl insertSegmentWithTitle: @" 8 Digits" atIndex: OTPTokenDigitsIndex8 animated: NO ];
302
+ _digitCountCell.segmentedControl .selectedSegmentIndex = OTPTokenDigitsIndex6;
303
+ }
304
+ return _digitCountCell;
305
+ }
306
+
307
+ - (OTPSegmentedControlCell *)algorithmCell
308
+ {
309
+ if (!_algorithmCell) {
310
+ _algorithmCell = [OTPSegmentedControlCell cell ];
311
+ [_algorithmCell.segmentedControl insertSegmentWithTitle: @" SHA-1" atIndex: OTPTokenAlgorithmIndexSHA1 animated: NO ];
312
+ [_algorithmCell.segmentedControl insertSegmentWithTitle: @" SHA-256" atIndex: OTPTokenAlgorithmIndexSHA256 animated: NO ];
313
+ [_algorithmCell.segmentedControl insertSegmentWithTitle: @" SHA-512" atIndex: OTPTokenAlgorithmIndexSHA512 animated: NO ];
314
+ _algorithmCell.segmentedControl .selectedSegmentIndex = OTPTokenAlgorithmIndexSHA1;
315
+ }
316
+ return _algorithmCell;
317
+ }
318
+
192
319
193
320
#pragma mark - UITableViewDelegate
194
321
@@ -204,6 +331,39 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce
204
331
}
205
332
}
206
333
334
+ - (CGFloat)tableView : (UITableView *)tableView heightForHeaderInSection : (NSInteger )section
335
+ {
336
+ if (section == OTPTokenEntrySectionAdvanced) {
337
+ return 54 ;
338
+ }
339
+ return 1 ;
340
+ }
341
+
342
+ - (UIView *)tableView : (UITableView *)tableView viewForHeaderInSection : (NSInteger )section
343
+ {
344
+ if (section == OTPTokenEntrySectionAdvanced) {
345
+ UIButton *headerView = [UIButton new ];
346
+ [headerView setTitle: @" Advanced Options" forState: UIControlStateNormal];
347
+ headerView.titleLabel .textAlignment = NSTextAlignmentCenter;
348
+ headerView.titleLabel .textColor = [UIColor otpForegroundColor ];
349
+ headerView.titleLabel .font = [UIFont fontWithName: @" HelveticaNeue-Light" size: 16 ];
350
+ [headerView addTarget: self action: @selector (revealAdvancedOptions ) forControlEvents: UIControlEventTouchUpInside];
351
+ return headerView;
352
+ }
353
+ return nil ;
354
+ }
355
+
356
+ - (void )revealAdvancedOptions
357
+ {
358
+ if (!self.showsAdvancedOptions ) {
359
+ self.showsAdvancedOptions = YES ;
360
+ [self .tableView reloadSections: [NSIndexSet indexSetWithIndex: OTPTokenEntrySectionAdvanced] withRowAnimation: UITableViewRowAnimationAutomatic];
361
+ [self .tableView scrollToRowAtIndexPath: [NSIndexPath indexPathForRow: (OTPNumberOfTokenEntryAdvancedRows - 1 )
362
+ inSection: OTPTokenEntrySectionAdvanced]
363
+ atScrollPosition: UITableViewScrollPositionBottom animated: YES ];
364
+ }
365
+ }
366
+
207
367
208
368
#pragma mark - UITextFieldDelegate
209
369
0 commit comments