Commit 146ea30e5d
Unsigned
Layout: unified · split
octosentry.xcodeproj/project.pbxproj +4 −4
| @@ -396,7 +396,7 @@ | |||
| 396 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; | 396 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; |
| 397 | CODE_SIGN_STYLE = Automatic; | 397 | CODE_SIGN_STYLE = Automatic; |
| 398 | COMBINE_HIDPI_IMAGES = YES; | 398 | COMBINE_HIDPI_IMAGES = YES; |
| 399 | CURRENT_PROJECT_VERSION = 1; | 399 | CURRENT_PROJECT_VERSION = 2; |
| 400 | DEVELOPMENT_TEAM = ZCNAX3VL9D; | 400 | DEVELOPMENT_TEAM = ZCNAX3VL9D; |
| 401 | ENABLE_APP_SANDBOX = YES; | 401 | ENABLE_APP_SANDBOX = YES; |
| 402 | ENABLE_HARDENED_RUNTIME = YES; | 402 | ENABLE_HARDENED_RUNTIME = YES; |
| @@ -412,7 +412,7 @@ | |||
| 412 | "$(inherited)", | 412 | "$(inherited)", |
| 413 | "@executable_path/../Frameworks", | 413 | "@executable_path/../Frameworks", |
| 414 | ); | 414 | ); |
| 415 | MARKETING_VERSION = 1.0.0; | 415 | MARKETING_VERSION = 1.0.1; |
| 416 | PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.octosentry; | 416 | PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.octosentry; |
| 417 | PRODUCT_NAME = "$(TARGET_NAME)"; | 417 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 418 | REGISTER_APP_GROUPS = YES; | 418 | REGISTER_APP_GROUPS = YES; |
| @@ -432,7 +432,7 @@ | |||
| 432 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; | 432 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; |
| 433 | CODE_SIGN_STYLE = Automatic; | 433 | CODE_SIGN_STYLE = Automatic; |
| 434 | COMBINE_HIDPI_IMAGES = YES; | 434 | COMBINE_HIDPI_IMAGES = YES; |
| 435 | CURRENT_PROJECT_VERSION = 1; | 435 | CURRENT_PROJECT_VERSION = 2; |
| 436 | DEVELOPMENT_TEAM = ZCNAX3VL9D; | 436 | DEVELOPMENT_TEAM = ZCNAX3VL9D; |
| 437 | ENABLE_APP_SANDBOX = YES; | 437 | ENABLE_APP_SANDBOX = YES; |
| 438 | ENABLE_HARDENED_RUNTIME = YES; | 438 | ENABLE_HARDENED_RUNTIME = YES; |
| @@ -448,7 +448,7 @@ | |||
| 448 | "$(inherited)", | 448 | "$(inherited)", |
| 449 | "@executable_path/../Frameworks", | 449 | "@executable_path/../Frameworks", |
| 450 | ); | 450 | ); |
| 451 | MARKETING_VERSION = 1.0.0; | 451 | MARKETING_VERSION = 1.0.1; |
| 452 | PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.octosentry; | 452 | PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.octosentry; |
| 453 | PRODUCT_NAME = "$(TARGET_NAME)"; | 453 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 454 | REGISTER_APP_GROUPS = YES; | 454 | REGISTER_APP_GROUPS = YES; |
octosentry/SecurityEventStore.swift +11 −3
| @@ -121,13 +121,21 @@ final class SecurityEventStore { | |||
| 121 | watchListErrorMessage = "Enter a repo as \"owner/repo\"." | 121 | watchListErrorMessage = "Enter a repo as \"owner/repo\"." |
| 122 | return | 122 | return |
| 123 | } | 123 | } |
| 124 | // Store the canonical "owner/repo" rather than the raw input, so | ||
| 125 | // stray slashes (e.g. "owner/repo/") can't produce a malformed | ||
| 126 | // entry that silently 404s on refresh. | ||
| 127 | let repoFullName = "\(parts[0])/\(parts[1])" | ||
| 124 | 128 | ||
| 125 | var state = await persistenceStore.load() | 129 | var state = await persistenceStore.load() |
| 126 | guard !state.watchedRepos.contains(trimmed) else { | 130 | // GitHub owner/repo names are case-insensitive, so treat entries |
| 127 | watchListErrorMessage = "\(trimmed) is already watched." | 131 | // that differ only in case as the same watched repo. |
| 132 | guard !state.watchedRepos.contains(where: { | ||
| 133 | $0.caseInsensitiveCompare(repoFullName) == .orderedSame | ||
| 134 | }) else { | ||
| 135 | watchListErrorMessage = "\(repoFullName) is already watched." | ||
| 128 | return | 136 | return |
| 129 | } | 137 | } |
| 130 | state.watchedRepos.append(trimmed) | 138 | state.watchedRepos.append(repoFullName) |
| 131 | await persistenceStore.save(state) | 139 | await persistenceStore.save(state) |
| 132 | watchedRepos = state.watchedRepos | 140 | watchedRepos = state.watchedRepos |
| 133 | 141 | ||