├── .gitattributes ├── Documentation ├── PKI_Specification.pdf ├── Examples │ ├── example_qr_vaccine_dose1.png │ ├── example_qr_vaccine_dose2.png │ └── example_qr_vaccine_recovery.png └── COVID_Pass_International_Digital_QR_Code-Tech_Summary.pdf ├── NHSCovidPassVerifier.iOS ├── Resources │ ├── info.png │ ├── github.png │ ├── info@2x.png │ ├── info@3x.png │ ├── arrow_back.png │ ├── clock_icon.png │ ├── github@2x.png │ ├── github@3x.png │ ├── help_icon.png │ ├── minus_icon.png │ ├── plus_icon.png │ ├── tick_mark.png │ ├── valid_icon.png │ ├── chevron_left.png │ ├── help_icon@2x.png │ ├── help_icon@3x.png │ ├── plus_icon@2x.png │ ├── plus_icon@3x.png │ ├── tick_mark@2x.png │ ├── tick_mark@3x.png │ ├── chevron_left@2x.png │ ├── chevron_left@3x.png │ ├── clock_icon@2x.png │ ├── clock_icon@3x.png │ ├── minus_icon@2x.png │ ├── minus_icon@3x.png │ ├── nhs_logo_simple.png │ ├── nhs_logo_white.png │ ├── qr_code_scanner.png │ ├── valid_icon@2x.png │ ├── valid_icon@3x.png │ ├── exclamation_mark.png │ ├── baseline_expand_less.png │ ├── baseline_expand_more.png │ ├── exclamation_mark@2x.png │ ├── exclamation_mark@3x.png │ ├── qr_code_scanner@2x.png │ ├── qr_code_scanner@3x.png │ ├── baseline_expand_less@2x.png │ ├── baseline_expand_less@3x.png │ ├── baseline_expand_more@2x.png │ ├── baseline_expand_more@3x.png │ └── IOSPageRenderer.cs ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── 20.png │ │ ├── 29.png │ │ ├── 40.png │ │ ├── 58.png │ │ ├── 60.png │ │ ├── 76.png │ │ ├── 80.png │ │ ├── 87.png │ │ ├── 1024.png │ │ ├── 120-1.png │ │ ├── 120.png │ │ ├── 152.png │ │ ├── 167.png │ │ ├── 180.png │ │ ├── 40-1.png │ │ ├── 40-2.png │ │ ├── 58-1.png │ │ └── 80-1.png │ └── AppIcon-1.appiconset │ │ ├── 120.png │ │ ├── 180.png │ │ ├── 20.png │ │ ├── 40.png │ │ ├── 58.png │ │ ├── 60.png │ │ ├── 80.png │ │ ├── 87.png │ │ ├── 120-1.png │ │ └── 40-1.png ├── Entitlements.plist ├── Main.cs ├── Properties │ └── AssemblyInfo.cs ├── Services │ ├── IosDeeplinkingService.cs │ └── ConfigurationProvider.cs ├── FontSizeLabelEffect.cs ├── CustomRenderers │ └── CustomScannerPageRenderer.cs └── Info.plist ├── NHSCovidPassVerifier ├── Properties │ └── launchSettings.json ├── Models │ ├── Logging │ │ └── LogSeverity.cs │ ├── TermsAndConditionsAgreed.cs │ ├── International │ │ ├── InternationalEnabled.cs │ │ ├── InternationalCertificate.cs │ │ ├── InternationalQrCode.cs │ │ ├── InternationalCertificateSubject.cs │ │ ├── Items │ │ │ ├── InternationalCertificateRecovery.cs │ │ │ ├── InternationalCertificateTestResult.cs │ │ │ └── InternationalCertificateVaccination.cs │ │ ├── EuHcertV1Schema.cs │ │ └── InternationalCertificatePayload.cs │ ├── Interfaces │ │ ├── ICertificate.cs │ │ ├── ICertificatePayload.cs │ │ └── IInternationalResultCard.cs │ ├── Dtos │ │ └── JwkDto.cs │ ├── SubjectPublicKeyInfoDto.cs │ ├── NhsAppResult.cs │ ├── DomesticCertificatePayload.cs │ ├── ApiResponse.cs │ ├── DomesticCertificate.cs │ └── Cose │ │ ├── HeaderParameterKey.cs │ │ └── SignatureAlgorithm.cs ├── Services │ ├── Interfaces │ │ ├── IZLibService.cs │ │ ├── IConsoleService.cs │ │ ├── IBase45Service.cs │ │ ├── IDeeplinkingService.cs │ │ ├── IAppCenterService.cs │ │ ├── IRestClient.cs │ │ ├── ILoggingService.cs │ │ ├── IJwkRepository.cs │ │ ├── IStatusBarService.cs │ │ ├── ICommonSettingsService.cs │ │ ├── IInternationalEnabledService.cs │ │ ├── IConfigurationProvider.cs │ │ ├── ISettingsService.cs │ │ ├── ISecureStorageService.cs │ │ ├── IQrDecoderService.cs │ │ ├── IQrValidatorService.cs │ │ └── IJwkService.cs │ ├── ErrorHandlers │ │ ├── IAppErrorHandler.cs │ │ ├── AppErrorHandler.cs │ │ └── SignatureVerificationException.cs │ ├── ConsoleService.cs │ ├── Utils │ │ ├── CborUtils.cs │ │ └── TaskUtils.cs │ ├── CachedLocaleReader.cs │ ├── AppCenterService.cs │ ├── Repositories │ │ ├── JwkRepository.cs │ │ └── SecureStorageService.cs │ ├── ZLibService.cs │ ├── LocaleService.cs │ ├── Mocks │ │ └── MockCommonSettingsService.cs │ └── InternationalEnabledService.cs ├── Enums │ ├── CertificateState.cs │ ├── InfoResultType.cs │ ├── NhsPageState.cs │ ├── QrCodeScannerStates.cs │ ├── CertificateType.cs │ └── NhsColour.cs ├── Configuration │ └── appsettings.json ├── Views │ ├── Elements │ │ ├── ScannerTestResult.xaml.cs │ │ ├── ScannerRecoveryResult.xaml.cs │ │ ├── ScannerVaccinationResult.xaml.cs │ │ ├── DropDownMenu.xaml.cs │ │ ├── Helpers │ │ │ └── InternationalResultCardDataTemplateSelector.cs │ │ ├── ScannerResultElements │ │ │ ├── ExpiredCode.xaml.cs │ │ │ ├── ValidCode.xaml.cs │ │ │ ├── InvalidCode.xaml.cs │ │ │ ├── ExpiresDateTimeText.xaml.cs │ │ │ ├── ExpiresDateTimeText.xaml │ │ │ └── InvalidCode.xaml │ │ ├── NhsHeader.xaml │ │ ├── MenuItem.xaml │ │ ├── ScannerResultEntry.xaml │ │ ├── ScannerVaccinationResultEntry.xaml │ │ ├── MenuItem.xaml.cs │ │ └── AboutPageExpander.xaml.cs │ ├── AboutPage.xaml.cs │ ├── NhsSplashPage.xaml.cs │ ├── FAQPage.xaml.cs │ ├── ApprovePage.xaml.cs │ ├── ResultInfoPage.xaml.cs │ ├── ErrorPage.xaml.cs │ ├── AccessibilityPage.xaml.cs │ ├── PrivacyPolicyPage.xaml.cs │ ├── TermsAndConditionsPage.xaml.cs │ ├── LandingPage.xaml.cs │ ├── ScannerResultInternationalCodePage.xaml.cs │ ├── NhsSplashPage.xaml │ └── ScannerResultPage.xaml.cs ├── Utils │ ├── PermissionUtils.cs │ ├── SetDashIfNoValueUtil.cs │ ├── Extensions.cs │ ├── HyperlinkImage.cs │ ├── HyperlinkSpan.cs │ └── DateUtils.cs ├── ViewModels │ ├── NhsSplashViewModel.cs │ ├── Base │ │ └── BaseBindableObject.cs │ ├── FAQViewModel.cs │ └── ApprovePageViewModel.cs └── Controls │ └── Converters │ ├── NullToVisibilityConverter.cs │ ├── InverseBoolConverter.cs │ ├── DateTimeToResultFormatConverter.cs │ └── EpochDatetimeConverter.cs ├── NHSCovidPassVerifier.Android ├── Resources │ ├── drawable-hdpi │ │ ├── info.png │ │ ├── github.png │ │ ├── help_icon.png │ │ ├── plus_icon.png │ │ ├── tick_mark.png │ │ ├── chevron_left.png │ │ ├── clock_icon.png │ │ ├── minus_icon.png │ │ ├── valid_icon.png │ │ ├── exclamation_mark.png │ │ ├── qr_code_scanner.png │ │ ├── icon_down_triangle.png │ │ ├── icon_right_triangle.png │ │ ├── baseline_expand_less.png │ │ └── baseline_expand_more.png │ ├── drawable-mdpi │ │ ├── info.png │ │ ├── github.png │ │ ├── help_icon.png │ │ ├── plus_icon.png │ │ ├── tick_mark.png │ │ ├── chevron_left.png │ │ ├── clock_icon.png │ │ ├── minus_icon.png │ │ ├── valid_icon.png │ │ ├── exclamation_mark.png │ │ ├── qr_code_scanner.png │ │ ├── icon_down_triangle.png │ │ ├── icon_right_triangle.png │ │ ├── baseline_expand_less.png │ │ └── baseline_expand_more.png │ ├── drawable-xhdpi │ │ ├── github.png │ │ ├── info.png │ │ ├── clock_icon.png │ │ ├── help_icon.png │ │ ├── minus_icon.png │ │ ├── plus_icon.png │ │ ├── tick_mark.png │ │ ├── valid_icon.png │ │ ├── chevron_left.png │ │ ├── exclamation_mark.png │ │ ├── qr_code_scanner.png │ │ ├── icon_down_triangle.png │ │ ├── baseline_expand_less.png │ │ ├── baseline_expand_more.png │ │ └── icon_right_triangle.png │ ├── drawable-xxhdpi │ │ ├── info.png │ │ ├── github.png │ │ ├── clock_icon.png │ │ ├── help_icon.png │ │ ├── minus_icon.png │ │ ├── plus_icon.png │ │ ├── tick_mark.png │ │ ├── valid_icon.png │ │ ├── chevron_left.png │ │ ├── qr_code_scanner.png │ │ ├── exclamation_mark.png │ │ ├── baseline_expand_less.png │ │ ├── baseline_expand_more.png │ │ ├── icon_down_triangle.png │ │ └── icon_right_triangle.png │ ├── drawable-xxxhdpi │ │ ├── info.png │ │ ├── github.png │ │ ├── help_icon.png │ │ ├── plus_icon.png │ │ ├── tick_mark.png │ │ ├── clock_icon.png │ │ ├── minus_icon.png │ │ ├── valid_icon.png │ │ ├── chevron_left.png │ │ ├── exclamation_mark.png │ │ ├── qr_code_scanner.png │ │ ├── icon_down_triangle.png │ │ ├── icon_right_triangle.png │ │ ├── baseline_expand_less.png │ │ └── baseline_expand_more.png │ ├── drawable │ │ ├── arrow_back.png │ │ ├── nhs_logo_white.png │ │ ├── nhs_logo_simple.png │ │ └── nhs_white_splash.xml │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_square.png │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_square.png │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_square.png │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_square.png │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_square.png │ ├── xml │ │ └── file_paths.xml │ ├── mipmap-anydpi-v26 │ │ ├── icon.xml │ │ └── icon_round.xml │ ├── values │ │ ├── colors.xml │ │ └── styles.xml │ ├── layout │ │ ├── Toolbar.xml │ │ └── Tabbar.xml │ └── AboutResources.txt ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Assets │ └── AboutAssets.txt ├── CustomRenderers │ └── CustomButtonRenderer.cs ├── Services │ ├── AndroidDeeplinkingService.cs │ ├── StatusBarService.cs │ └── ConfigurationProvider.cs └── SplashActivity.cs ├── CODEOWNERS ├── Directory.Build.props ├── Nuget.Config ├── NHSCovidPassVerifier.Tests ├── ViewModelTests │ ├── NhsSplashViewModelTests.cs │ ├── LandingViewModelTests.cs │ ├── ApprovePageViewModelTests.cs │ ├── FAQViewModelTests.cs │ ├── QrScannerViewModelTests.cs │ ├── NavigationTests.cs │ └── PrivacyPolicyViewModelTests.cs ├── UtilsTests │ ├── CBORUtilsTests.cs │ ├── NhsColourTest.cs │ ├── Asn1UtilsTests.cs │ ├── SetDashIfNoValueUtilTests.cs │ └── DateUtilsTests.cs ├── MockServices │ ├── MockConfigurationProvider.cs │ ├── MockSecureStorageService.cs │ ├── MockCommonSettingsService.cs │ ├── MockSettingsService.cs │ └── MockNavigationService.cs ├── NHSCovidPassVerifier.Tests.csproj ├── TestData │ └── InternationalCardData.cs └── ServicesTests │ └── RepositoriesTests │ └── QrECValidatorServiceTests.cs ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE └── contributing.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Documentation/PKI_Specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/Documentation/PKI_Specification.pdf -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/info.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/github.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/info@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/info@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/info@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "NHSCovidPassVerifier": { 4 | "commandName": "Project" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/arrow_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/arrow_back.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/clock_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/clock_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/github@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/github@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/github@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/github@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/help_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/help_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/minus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/minus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/plus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/tick_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/tick_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/valid_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/valid_icon.png -------------------------------------------------------------------------------- /Documentation/Examples/example_qr_vaccine_dose1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/Documentation/Examples/example_qr_vaccine_dose1.png -------------------------------------------------------------------------------- /Documentation/Examples/example_qr_vaccine_dose2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/Documentation/Examples/example_qr_vaccine_dose2.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/chevron_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/chevron_left.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/help_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/help_icon@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/help_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/help_icon@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/plus_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/plus_icon@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/plus_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/plus_icon@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/tick_mark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/tick_mark@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/tick_mark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/tick_mark@3x.png -------------------------------------------------------------------------------- /Documentation/Examples/example_qr_vaccine_recovery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/Documentation/Examples/example_qr_vaccine_recovery.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/chevron_left@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/chevron_left@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/chevron_left@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/chevron_left@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/clock_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/clock_icon@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/clock_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/clock_icon@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/minus_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/minus_icon@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/minus_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/minus_icon@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/nhs_logo_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/nhs_logo_simple.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/nhs_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/nhs_logo_white.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/qr_code_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/qr_code_scanner.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/valid_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/valid_icon@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/valid_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/valid_icon@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/exclamation_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/exclamation_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/baseline_expand_less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/baseline_expand_less.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/baseline_expand_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/baseline_expand_more.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/exclamation_mark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/exclamation_mark@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/exclamation_mark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/exclamation_mark@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/qr_code_scanner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/qr_code_scanner@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/qr_code_scanner@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/qr_code_scanner@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/info.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/info.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/github.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/github.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/github.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/info.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/info.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/info.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable/arrow_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable/arrow_back.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/baseline_expand_less@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/baseline_expand_less@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/baseline_expand_less@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/baseline_expand_less@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/baseline_expand_more@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/baseline_expand_more@2x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/baseline_expand_more@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Resources/baseline_expand_more@3x.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/help_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/help_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/plus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/tick_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/tick_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/help_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/help_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/plus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/tick_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/tick_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/github.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/github.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable/nhs_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable/nhs_logo_white.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/chevron_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/chevron_left.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/clock_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/clock_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/minus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/minus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/valid_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/valid_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/chevron_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/chevron_left.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/clock_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/clock_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/minus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/minus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/valid_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/valid_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/clock_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/clock_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/help_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/help_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/minus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/minus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/plus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/tick_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/tick_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/valid_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/valid_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/clock_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/clock_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/help_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/help_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/minus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/minus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/plus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/tick_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/tick_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/valid_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/valid_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/help_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/help_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/plus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/tick_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/tick_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable/nhs_logo_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable/nhs_logo_simple.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/120.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/180.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/20.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/40.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/58.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/60.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/80.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/87.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/120-1.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/40-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/40-1.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/40-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/40-2.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/58-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/58-1.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/80-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon.appiconset/80-1.png -------------------------------------------------------------------------------- /Documentation/COVID_Pass_International_Digital_QR_Code-Tech_Summary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/Documentation/COVID_Pass_International_Digital_QR_Code-Tech_Summary.pdf -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/chevron_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/chevron_left.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/chevron_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/chevron_left.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/clock_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/clock_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/minus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/minus_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/valid_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/valid_icon.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/120-1.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/40-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.iOS/Assets.xcassets/AppIcon-1.appiconset/40-1.png -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in the repo. 5 | * @AmitPore 6 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/exclamation_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/exclamation_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/qr_code_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/qr_code_scanner.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/exclamation_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/exclamation_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/qr_code_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/qr_code_scanner.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/exclamation_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/exclamation_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/qr_code_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/qr_code_scanner.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/qr_code_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/qr_code_scanner.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/chevron_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/chevron_left.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-hdpi/ic_launcher_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-hdpi/ic_launcher_square.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-mdpi/ic_launcher_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-mdpi/ic_launcher_square.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-xhdpi/ic_launcher_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-xhdpi/ic_launcher_square.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/icon_down_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/icon_down_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/icon_right_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/icon_right_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/icon_down_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/icon_down_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/icon_right_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/icon_right_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/icon_down_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/icon_down_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/exclamation_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/exclamation_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/exclamation_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/exclamation_mark.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/qr_code_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/qr_code_scanner.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-xxhdpi/ic_launcher_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-xxhdpi/ic_launcher_square.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-xxxhdpi/ic_launcher_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/mipmap-xxxhdpi/ic_launcher_square.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/baseline_expand_less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/baseline_expand_less.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-hdpi/baseline_expand_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-hdpi/baseline_expand_more.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/baseline_expand_less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/baseline_expand_less.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-mdpi/baseline_expand_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-mdpi/baseline_expand_more.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/baseline_expand_less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/baseline_expand_less.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/baseline_expand_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/baseline_expand_more.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/icon_right_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xhdpi/icon_right_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/baseline_expand_less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/baseline_expand_less.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/baseline_expand_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/baseline_expand_more.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/icon_down_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/icon_down_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/icon_right_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxhdpi/icon_right_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/icon_down_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/icon_down_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/icon_right_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/icon_right_triangle.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Logging/LogSeverity.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Models.Logging 2 | { 3 | public enum LogSeverity 4 | { 5 | INFO, 6 | WARNING, 7 | ERROR 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IZLibService.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Services.Interfaces 2 | { 3 | public interface IZLibService 4 | { 5 | public byte[] DecompressData(byte[] inData); 6 | } 7 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/baseline_expand_less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/baseline_expand_less.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/baseline_expand_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ukhsa-collaboration/covid-pass-verifier/HEAD/NHSCovidPassVerifier.Android/Resources/drawable-xxxhdpi/baseline_expand_more.png -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/TermsAndConditionsAgreed.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Models 2 | { 3 | public class TermsAndConditionsAgreed 4 | { 5 | public bool IsTermsAndConditionsAgreed { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Enums/CertificateState.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Enums 2 | { 3 | public enum CertificateState 4 | { 5 | Unknown = 0 , 6 | Valid = 1 , 7 | Invalid = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | true 5 | 6 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Enums/InfoResultType.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Enums 2 | { 3 | public enum InfoResultType 4 | { 5 | Vaccination = 0, 6 | Recovery = 1, 7 | TestResult = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/InternationalEnabled.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Models.International 2 | { 3 | public class InternationalEnabled 4 | { 5 | public bool IsInternationalEnabled { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Nuget.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/ErrorHandlers/IAppErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NHSCovidPassVerifier.Services.ErrorHandlers 4 | { 5 | public interface IAppErrorHandler 6 | { 7 | void HandleError(Exception ex); 8 | } 9 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Interfaces/ICertificate.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Enums; 2 | 3 | namespace NHSCovidPassVerifier.Models.Interfaces 4 | { 5 | public interface ICertificate 6 | { 7 | public CertificateType GetCertificateType(); 8 | } 9 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Dtos/JwkDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NHSCovidPassVerifier.Models.Dtos 4 | { 5 | public class JwkDto 6 | { 7 | public string Jwk { get; set; } 8 | 9 | public DateTime TimeReceived { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Interfaces/ICertificatePayload.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Enums; 2 | 3 | namespace NHSCovidPassVerifier.Models.Interfaces 4 | { 5 | public interface ICertificatePayload 6 | { 7 | public CertificateType GetCertificateType(); 8 | } 9 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Interfaces/IInternationalResultCard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NHSCovidPassVerifier.Models.Interfaces 4 | { 5 | public interface IInternationalResultCard : IComparable, IComparable 6 | { 7 | public DateTime? GetSortByDate(); 8 | } 9 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IConsoleService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace NHSCovidPassVerifier.Services.Interfaces 6 | { 7 | public interface IConsoleService 8 | { 9 | void PrintToDebugConsole(string s); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-anydpi-v26/icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/mipmap-anydpi-v26/icon_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/ConsoleService.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Services.Interfaces; 2 | 3 | namespace NHSCovidPassVerifier.Services 4 | { 5 | public class ConsoleService : IConsoleService 6 | { 7 | public void PrintToDebugConsole(string s) 8 | { 9 | System.Diagnostics.Debug.Print(s); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Configuration/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "GetJwkUrl": "", 3 | "AndroidAppCenterKey": "", 4 | "iOSAppCenterKey": "", 5 | "ScannerResultShownDuration": "3000", 6 | "PressedToReleasedCloseInterval": "100", 7 | "JwkValidForHours": "24", 8 | "DefaultTimeout": "15", 9 | "IsScreenShotAllowed": "false", 10 | "PublicKeys": [] 11 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/SubjectPublicKeyInfoDto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace NHSCovidPassVerifier.Models 4 | { 5 | public class SubjectPublicKeyInfoDto 6 | { 7 | [JsonProperty("kid")] 8 | public string Kid { get; set; } 9 | [JsonProperty("publicKey")] 10 | public string PublicKey { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | keychain-access-groups 6 | 7 | $(AppIdentifierPrefix)uk.gov.dhsc.healthrecord.xamarinessentials 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerTestResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace NHSCovidPassVerifier.Views.Elements 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class ScannerTestResult : Grid 8 | { 9 | public ScannerTestResult() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IBase45Service.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Services.Interfaces 2 | { 3 | public interface IBase45Service 4 | {/// 5 | /// Decode Base 45 String to Byte Array 6 | /// 7 | /// Base 45 String 8 | /// Decoded Byte Array 9 | public byte[] Base45Decode(string value); 10 | } 11 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Enums/NhsPageState.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Enums 2 | { 3 | public enum NhsPageState 4 | { 5 | Success = 200, 6 | CertificateNotFound = 204, 7 | Unauthorized = 401, 8 | NotFound = 404, 9 | MethodNotAllowd = 405, 10 | RequestTimeout = 408, 11 | InternalServerError = 500, 12 | ServiceNotAvailable = 503 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/NhsAppResult.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Enums; 2 | 3 | namespace NHSCovidPassVerifier.Models 4 | { 5 | public class NhsAppResult 6 | { 7 | public T Data { get; set; } 8 | 9 | public NhsPageState State { get; set; } 10 | 11 | public void SetState(int statusCode) 12 | { 13 | State = (NhsPageState)statusCode; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerRecoveryResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace NHSCovidPassVerifier.Views.Elements 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class ScannerRecoveryResult : Grid 8 | { 9 | public ScannerRecoveryResult() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #005EB8 4 | #61C897 5 | #005EB8 6 | #330072 7 | #DBDBDB 8 | #DBDBDB 9 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/layout/Toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerVaccinationResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace NHSCovidPassVerifier.Views.Elements 5 | { 6 | [XamlCompilation(XamlCompilationOptions.Compile)] 7 | public partial class ScannerVaccinationResult : Grid 8 | { 9 | public ScannerVaccinationResult() 10 | { 11 | InitializeComponent(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IDeeplinkingService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace NHSCovidPassVerifier.Services.Interfaces 4 | { 5 | public interface IDeeplinkingService 6 | { 7 | /// 8 | /// Task which opens native application settings 9 | /// 10 | /// Successfully completed Task 11 | Task GoToAppSettings(); 12 | } 13 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Utils/CborUtils.cs: -------------------------------------------------------------------------------- 1 | using PeterO.Cbor; 2 | 3 | namespace NHSCovidPassVerifier.Services.Utils 4 | { 5 | public class CborUtils 6 | { 7 | public static string ToJson(byte[] cborDataFormatBytes) 8 | { 9 | var cborObjectFromBytes = CBORObject.DecodeFromBytes(cborDataFormatBytes); 10 | var jsonString = cborObjectFromBytes.ToJSONString(); 11 | 12 | return jsonString; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IAppCenterService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AppCenter.Crashes; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace NHSCovidPassVerifier.Services 6 | { 7 | public interface IAppCenterService 8 | { 9 | void TrackEvent(string name, IDictionary properties = null); 10 | 11 | void TrackError(Exception exception, IDictionary properties = null, params ErrorAttachmentLog[] attachments); 12 | } 13 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/InternationalCertificate.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Enums; 2 | using NHSCovidPassVerifier.Models.Interfaces; 3 | 4 | namespace NHSCovidPassVerifier.Models.International 5 | { 6 | public class InternationalCertificate : ICertificate 7 | { 8 | public InternationalCertificatePayload DecodedModel { get; set; } 9 | public CertificateType GetCertificateType() 10 | { 11 | return CertificateType.International; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/drawable/nhs_white_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 16 | 17 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Utils/PermissionUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Xamarin.Essentials; 3 | 4 | namespace NHSCovidPassVerifier.Utils 5 | { 6 | public static class PermissionUtils 7 | { 8 | public static async Task CheckAndRequestCameraPermission() 9 | { 10 | return await Permissions.CheckStatusAsync() == PermissionStatus.Granted 11 | || await Permissions.RequestAsync() == PermissionStatus.Granted; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/AboutPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using Xamarin.Forms; 4 | using Xamarin.Forms.Xaml; 5 | 6 | namespace NHSCovidPassVerifier.Views 7 | { 8 | [XamlCompilation(XamlCompilationOptions.Compile)] 9 | public partial class AboutPage : ContentPage 10 | { 11 | public AboutPage() 12 | { 13 | InitializeComponent(); 14 | BindingContext = IoCContainer.Resolve(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/InternationalQrCode.cs: -------------------------------------------------------------------------------- 1 | namespace NHSCovidPassVerifier.Models.International 2 | { 3 | public class InternationalQrCode 4 | { 5 | public string Name { get; set; } 6 | public string BatchNumber { get; set; } 7 | public string Issuer { get; set; } 8 | public string Id { get; set; } 9 | public string DiseaseTarget { get; set; } 10 | public string CountryOfVaccination { get; set; } 11 | public string AdministeringCentre { get; set; } 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/CachedLocaleReader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using I18NPortable; 4 | using I18NPortable.JsonReader; 5 | 6 | namespace NHSCovidPassVerifier.Services 7 | { 8 | public class CachedLocaleReader : ILocaleReader 9 | { 10 | private static Dictionary _cachedDictionary; 11 | 12 | public Dictionary Read(Stream stream) 13 | { 14 | return _cachedDictionary ??= new JsonKvpReader().Read(stream); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/NhsSplashPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using Xamarin.Forms; 4 | using Xamarin.Forms.Xaml; 5 | 6 | namespace NHSCovidPassVerifier.Views 7 | { 8 | [XamlCompilation(XamlCompilationOptions.Compile)] 9 | public partial class NhsSplashPage : ContentPage 10 | { 11 | public NhsSplashPage() 12 | { 13 | InitializeComponent(); 14 | BindingContext = IoCContainer.Resolve(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/DropDownMenu.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using Xamarin.Forms; 4 | using Xamarin.Forms.Xaml; 5 | 6 | namespace NHSCovidPassVerifier.Views.Elements 7 | { 8 | [XamlCompilation(XamlCompilationOptions.Compile)] 9 | public partial class DropDownMenu : Frame 10 | { 11 | public DropDownMenu() 12 | { 13 | InitializeComponent(); 14 | BindingContext = IoCContainer.Resolve(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/ViewModels/NhsSplashViewModel.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.ViewModels.Base; 2 | using Xamarin.Forms; 3 | using I18NPortable; 4 | 5 | namespace NHSCovidPassVerifier.ViewModels 6 | { 7 | public class NhsSplashViewModel : BaseViewModel 8 | { 9 | public string LoadingText { get; set; } 10 | 11 | public NhsSplashViewModel() 12 | { 13 | InitText(); 14 | } 15 | 16 | private void InitText() 17 | { 18 | LoadingText = "NHS_SPLASH_TEXT".Translate(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/InternationalCertificateSubject.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace NHSCovidPassVerifier.Models.International 4 | { 5 | public class InternationalCertificateSubject 6 | { 7 | [JsonProperty("gn")] 8 | public string GivenName { get; set; } 9 | [JsonProperty("gnt")] 10 | public string GivenNameTransliterated { get; set; } 11 | [JsonProperty("fn")] 12 | public string FamilyName { get; set; } 13 | [JsonProperty("fnt")] 14 | public string FamilyNameTransliterated { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IRestClient.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Net.Http; 3 | using System.Threading.Tasks; 4 | using NHSCovidPassVerifier.Models; 5 | 6 | namespace NHSCovidPassVerifier.Services.Interfaces 7 | { 8 | public interface IRestClient 9 | { 10 | /// 11 | /// Gets a file stream asynchronously. 12 | /// 13 | /// url to get file from 14 | /// An Apiresponse with the file stream. 15 | Task> GetFileAsStreamAsync(string url); 16 | } 17 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Utils/TaskUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using NHSCovidPassVerifier.Services.ErrorHandlers; 4 | 5 | namespace NHSCovidPassVerifier.Services.Utils 6 | { 7 | public static class TaskUtils 8 | { 9 | public static async void FireAndForgetSafeAsync(this Task task, IAppErrorHandler handler) 10 | { 11 | try 12 | { 13 | await task; 14 | } 15 | catch (Exception ex) 16 | { 17 | handler?.HandleError(ex); 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/ErrorHandlers/AppErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Configuration; 3 | using NHSCovidPassVerifier.Models.Logging; 4 | using NHSCovidPassVerifier.Services.Interfaces; 5 | 6 | namespace NHSCovidPassVerifier.Services.ErrorHandlers 7 | { 8 | public class AppErrorHandler : IAppErrorHandler 9 | { 10 | public void HandleError(Exception ex) 11 | { 12 | var loggingService = IoCContainer.Resolve(); 13 | loggingService.LogException(LogSeverity.ERROR, ex, $"Application Error: {ex.Message}"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/DomesticCertificatePayload.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Enums; 2 | using NHSCovidPassVerifier.Models.Interfaces; 3 | 4 | namespace NHSCovidPassVerifier.Models 5 | { 6 | public class DomesticCertificatePayload : ICertificatePayload 7 | { 8 | public DomesticCertificatePayload(string payloadContent) 9 | { 10 | PayloadContent = payloadContent; 11 | } 12 | public string PayloadContent { get; } 13 | 14 | public CertificateType GetCertificateType() 15 | { 16 | return CertificateType.Domestic; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Controls/Converters/NullToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace NHSCovidPassVerifier.Controls.Converters 6 | { 7 | public class NullToVisibilityConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return value != null; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | return value != null; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/ILoggingService.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models; 2 | using NHSCovidPassVerifier.Models.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace NHSCovidPassVerifier.Services.Interfaces 7 | { 8 | public interface ILoggingService 9 | { 10 | void LogException(LogSeverity severity, Exception e, string additionalInfo = null); 11 | void LogApiError(LogSeverity severity, ApiResponse apiResponse, string additionalInfo = null); 12 | void LogMessage(LogSeverity severity, string message, Dictionary customProperties = null); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/layout/Tabbar.xml: -------------------------------------------------------------------------------- 1 | 2 | HELLO -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IJwkRepository.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models.Dtos; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using NHSCovidPassVerifier.Models; 7 | using System.IO; 8 | 9 | namespace NHSCovidPassVerifier.Services.Interfaces 10 | { 11 | public interface IJwkRepository 12 | { 13 | /// 14 | /// Attempts to get the Jwk token from the apps jwkurl 15 | /// 16 | /// An ApiResponse with the jwk contents as a Stream 17 | Task> GetJwk(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/FAQPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Xaml; 11 | 12 | namespace NHSCovidPassVerifier.Views 13 | { 14 | [XamlCompilation(XamlCompilationOptions.Compile)] 15 | public partial class FAQPage : ContentPage 16 | { 17 | public FAQPage() 18 | { 19 | InitializeComponent(); 20 | BindingContext = IoCContainer.Resolve(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/NhsSplashViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.ViewModels; 2 | using I18NPortable; 3 | using NUnit.Framework; 4 | 5 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 6 | { 7 | [TestFixture] 8 | public class NhsSplashViewModelTests 9 | { 10 | private readonly NhsSplashViewModel _viewModel; 11 | 12 | public NhsSplashViewModelTests() 13 | { 14 | _viewModel = new NhsSplashViewModel(); 15 | } 16 | 17 | [Test] 18 | public void TestText() 19 | { 20 | Assert.AreEqual(this._viewModel.LoadingText, "NHS_SPLASH_TEXT".Translate()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Controls/Converters/InverseBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Text; 5 | using Xamarin.Forms; 6 | 7 | namespace NHSCovidPassVerifier.Controls.Converters 8 | { 9 | public class InverseBoolConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | return !(bool)value; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | return !(bool)value; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Utils/SetDashIfNoValueUtil.cs: -------------------------------------------------------------------------------- 1 | using I18NPortable; 2 | using System; 3 | using System.Globalization; 4 | 5 | namespace NHSCovidPassVerifier.Utils 6 | { 7 | public static class SetDashIfNoValueUtil 8 | { 9 | 10 | public static string SetDashIfNoValue(this string str) 11 | { 12 | return string.IsNullOrEmpty(str) ? "INTERNATIONAL_SCANNER_RESULT_BLANK_FIELD".Translate() : str; 13 | } 14 | 15 | public static string SetDashIfNoValue(this DateTime? val) 16 | { 17 | return val.HasValue ? val.Value.FormatDate() : "INTERNATIONAL_SCANNER_RESULT_BLANK_FIELD".Translate(); 18 | } 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/ApprovePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Xaml; 11 | 12 | namespace NHSCovidPassVerifier.Views 13 | { 14 | [XamlCompilation(XamlCompilationOptions.Compile)] 15 | public partial class ApprovePage : ContentPage 16 | { 17 | public ApprovePage() 18 | { 19 | InitializeComponent(); 20 | BindingContext = IoCContainer.Resolve(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/ResultInfoPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Xaml; 11 | 12 | namespace NHSCovidPassVerifier.Views 13 | { 14 | [XamlCompilation(XamlCompilationOptions.Compile)] 15 | public partial class ResultInfoPage : ContentPage 16 | { 17 | public ResultInfoPage() 18 | { 19 | InitializeComponent(); 20 | BindingContext = IoCContainer.Resolve(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/ErrorPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.ViewModels; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Xaml; 6 | 7 | namespace NHSCovidPassVerifier.Views 8 | { 9 | [XamlCompilation(XamlCompilationOptions.Compile)] 10 | public partial class ErrorPage : ContentPage 11 | { 12 | private readonly IStatusBarService _statusBarService = IoCContainer.Resolve(); 13 | 14 | public ErrorPage() 15 | { 16 | InitializeComponent(); 17 | BindingContext = IoCContainer.Resolve(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/AccessibilityPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Xaml; 11 | 12 | namespace NHSCovidPassVerifier.Views 13 | { 14 | [XamlCompilation(XamlCompilationOptions.Compile)] 15 | public partial class AccessibilityPage : ContentPage 16 | { 17 | public AccessibilityPage() 18 | { 19 | InitializeComponent(); 20 | BindingContext = IoCContainer.Resolve(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Enums/QrCodeScannerStates.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace NHSCovidPassVerifier.Enums 4 | { 5 | public enum QrCodeScannerStates 6 | { 7 | [Description("Valid Domestic QR Code")] 8 | ValidDomesticCertificate, 9 | 10 | 11 | [Description("Expired Domestic QR Code")] 12 | InvalidDomesticCertificate, 13 | 14 | [Description("Valid International QR Code")] 15 | ValidInternationalCertificate, 16 | 17 | [Description("Disabled International QR Code")] 18 | DisabledInternationalCertificate, 19 | 20 | [Description("QR Code Not Recognised")] 21 | InvalidScan 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/PrivacyPolicyPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Xaml; 11 | 12 | namespace NHSCovidPassVerifier.Views 13 | { 14 | [XamlCompilation(XamlCompilationOptions.Compile)] 15 | public partial class PrivacyPolicyPage : ContentPage 16 | { 17 | public PrivacyPolicyPage() 18 | { 19 | InitializeComponent(); 20 | BindingContext = IoCContainer.Resolve(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Resources/IOSPageRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Configuration; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | using Foundation; 5 | using HIPSTO.iOS.Platform.Renderers; 6 | using UIKit; 7 | using Xamarin.Forms; 8 | using Xamarin.Forms.Platform.iOS; 9 | 10 | [assembly: ExportRenderer(typeof(ContentPage), typeof(IOSPageRenderer))] 11 | namespace HIPSTO.iOS.Platform.Renderers 12 | { 13 | public class IOSPageRenderer : PageRenderer 14 | { 15 | public override void ViewWillAppear(bool animated) 16 | { 17 | base.ViewWillAppear(animated); 18 | IoCContainer.Resolve().SetDefaultStatusBar(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/TermsAndConditionsPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.ViewModels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Xaml; 11 | 12 | namespace NHSCovidPassVerifier.Views 13 | { 14 | [XamlCompilation(XamlCompilationOptions.Compile)] 15 | public partial class TermsAndConditionsPage : ContentPage 16 | { 17 | public TermsAndConditionsPage() 18 | { 19 | InitializeComponent(); 20 | BindingContext = IoCContainer.Resolve(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/LandingPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.Utils; 4 | using NHSCovidPassVerifier.ViewModels; 5 | using Xamarin.Forms; 6 | using Xamarin.Forms.Xaml; 7 | 8 | namespace NHSCovidPassVerifier.Views 9 | { 10 | [XamlCompilation(XamlCompilationOptions.Compile)] 11 | public partial class LandingPage : ContentPage 12 | { 13 | private readonly IStatusBarService _statusBarService = IoCContainer.Resolve(); 14 | 15 | public LandingPage() 16 | { 17 | InitializeComponent(); 18 | BindingContext = IoCContainer.Resolve(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Enums/CertificateType.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace NHSCovidPassVerifier.Enums 4 | { 5 | public enum CertificateType 6 | { 7 | International, 8 | Domestic 9 | } 10 | 11 | public static class CertificateTypeExtension 12 | { 13 | private static readonly Dictionary TokenTypeDictionary = new Dictionary 14 | { 15 | {"HC1", CertificateType.International} 16 | }; 17 | 18 | public static CertificateType GetCertificateType(string prefix) 19 | { 20 | return TokenTypeDictionary.TryGetValue(prefix, out var result) ? result : CertificateType.Domestic; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Models.Logging; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | using System; 5 | using UIKit; 6 | 7 | namespace NHSCovidPassVerifier.iOS 8 | { 9 | public class Application 10 | { 11 | static void Main(string[] args) 12 | { 13 | try 14 | { 15 | UIApplication.Main(args, null, "AppDelegate"); 16 | } 17 | catch (Exception e) 18 | { 19 | var loggingService = IoCContainer.Resolve(); 20 | loggingService.LogException(LogSeverity.ERROR, e); 21 | throw e; 22 | } 23 | 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/CustomRenderers/CustomButtonRenderer.cs: -------------------------------------------------------------------------------- 1 | using Android.Content; 2 | using NHSCovidPassVerifier.Droid; 3 | using Xamarin.Forms; 4 | using Xamarin.Forms.Platform.Android; 5 | 6 | [assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(CustomButtonRenderer))] 7 | namespace NHSCovidPassVerifier.Droid 8 | { 9 | public class CustomButtonRenderer : ButtonRenderer 10 | { 11 | public CustomButtonRenderer(Context context) : base(context) 12 | { 13 | AutoPackage = false; 14 | } 15 | 16 | protected override void OnElementChanged(ElementChangedEventArgs e) 17 | { 18 | base.OnElementChanged(e); 19 | Control?.SetPadding(0, 0, 0, 0); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IStatusBarService.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace NHSCovidPassVerifier.Services.Interfaces 4 | { 5 | public interface IStatusBarService 6 | { 7 | /// 8 | /// Sets the phones status bare color. 9 | /// 10 | /// Color to change the status bar to. 11 | void SetStatusBarColor(Color color); 12 | 13 | /// 14 | /// Sets the status bar to the default app color. 15 | /// 16 | void SetDefaultStatusBar(); 17 | 18 | /// 19 | /// Removes and updated the statusbar on iOS, does nothing on Android. 20 | /// 21 | void RemoveStatusBar(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/ApiResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace NHSCovidPassVerifier.Models 5 | { 6 | public class ApiResponse 7 | { 8 | public string Endpoint { get; } 9 | public string ResponseText { get; set; } 10 | public int StatusCode { get; set; } 11 | public Exception Exception { get; set; } 12 | 13 | public ApiResponse(string url) 14 | { 15 | Endpoint = url.Split(new string[]{"/"}, StringSplitOptions.None).Last(); 16 | } 17 | } 18 | 19 | public class ApiResponse : ApiResponse 20 | { 21 | public T Data { get; set; } 22 | 23 | public ApiResponse(string url) : base(url) 24 | { 25 | Data = default(T); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/DomesticCertificate.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Enums; 2 | using System; 3 | using NHSCovidPassVerifier.Models.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Models 6 | { 7 | public class DomesticCertificate : ICertificate 8 | { 9 | public string FullName { get; set; } 10 | 11 | public DateTime Expiry { get; set; } 12 | 13 | public CertificateState CertificateState => GetStatus(); 14 | 15 | public CertificateType GetCertificateType() 16 | { 17 | return CertificateType.Domestic; 18 | } 19 | 20 | private CertificateState GetStatus() 21 | { 22 | return Expiry >= DateTime.UtcNow ? CertificateState.Valid : CertificateState.Invalid; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/AppCenterService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AppCenter.Analytics; 2 | using Microsoft.AppCenter.Crashes; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace NHSCovidPassVerifier.Services 7 | { 8 | public class AppCenterService : IAppCenterService 9 | { 10 | public void TrackEvent(string name, IDictionary properties = null) 11 | { 12 | Analytics.TrackEvent(name, properties); 13 | } 14 | 15 | public void TrackError( 16 | Exception exception, 17 | IDictionary properties = null, 18 | params ErrorAttachmentLog[] attachments) 19 | { 20 | Crashes.TrackError(exception, properties, attachments); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/ScannerResultInternationalCodePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.ViewModels; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Xaml; 6 | 7 | namespace NHSCovidPassVerifier.Views 8 | { 9 | [XamlCompilation(XamlCompilationOptions.Compile)] 10 | public partial class ScannerResultInternationalCodePage : ContentPage 11 | { 12 | private readonly IStatusBarService _statusBarService = IoCContainer.Resolve(); 13 | public ScannerResultInternationalCodePage() 14 | { 15 | InitializeComponent(); 16 | BindingContext = IoCContainer.Resolve(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/ICommonSettingsService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace NHSCovidPassVerifier.Services.Interfaces 4 | { 5 | public interface ICommonSettingsService 6 | { 7 | IDictionary VaccineManufacturers { get; } 8 | IDictionary VaccineTypes { get; } 9 | IDictionary DiseasesTargeted { get; } 10 | IDictionary VaccineNames { get; } 11 | IDictionary ReadableVaccineNames { get; } 12 | IDictionary TestTypes { get; } 13 | IDictionary TestResults { get; } 14 | IEnumerable EnglishCertificateIssuers { get; } 15 | IDictionary InternationalMinimumDoses { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("NHSCovidPassVerifier.iOS")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("NHSCovidPassVerifier.iOS")] 9 | [assembly: AssemblyCopyright("Copyright © 2014")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")] 16 | 17 | [assembly: AssemblyVersion("1.0.0")] 18 | [assembly: AssemblyFileVersion("1.0.0")] 19 | 20 | #if DEBUG 21 | [assembly: AssemblyConfiguration("local")] 22 | #else 23 | [assembly: AssemblyConfiguration("Production")] 24 | #endif 25 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IInternationalEnabledService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace NHSCovidPassVerifier.Services.Interfaces 4 | { 5 | public interface IInternationalEnabledService 6 | { 7 | /// 8 | /// Get value of internationEnabled flag 9 | /// 10 | /// Boolean dependent on whether international QR codes are enabled or not 11 | public bool GetInternationalEnabled(); 12 | 13 | /// 14 | /// Set the internationEnabled flag 15 | /// 16 | /// The boolean value you wish to set the flag to 17 | /// Returns completed task 18 | public Task SetInternationalEnabled(bool newValue); 19 | } 20 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/UtilsTests/CBORUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Services.Utils; 3 | using NHSCovidPassVerifier.Utils; 4 | using I18NPortable; 5 | using NUnit.Framework; 6 | using PeterO.Cbor; 7 | 8 | namespace NHSCovidPassVerifier.Tests.UtilsTests 9 | { 10 | public class CBORUtilsTests 11 | { 12 | [TestCase((byte)0x02 , "2")] 13 | [TestCase((byte)0x22, "-3")] 14 | public void TestCBORToJson(byte inputByte, string result) 15 | { 16 | //Given 17 | byte[] bytes = new byte[] { 18 | inputByte, 19 | }; 20 | 21 | //When 22 | string returnedJsonString = CborUtils.ToJson(bytes); 23 | 24 | //Then 25 | Assert.AreEqual(returnedJsonString, result); 26 | } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Services/IosDeeplinkingService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Threading.Tasks; 4 | using NHSCovidPassVerifier.Services.Interfaces; 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace NHSCovidPassVerifier.iOS.Services 9 | { 10 | public class IosDeeplinkingService : IDeeplinkingService 11 | { 12 | public async Task GoToAppSettings() 13 | { 14 | try 15 | { 16 | await UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(UIApplication.OpenSettingsUrlString), 17 | new UIApplicationOpenUrlOptions()); 18 | } 19 | catch (Exception ex) 20 | { 21 | Debug.WriteLine($"Error attempting to deep-link to application settings: {ex}"); 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Repositories/JwkRepository.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using System.IO; 4 | using System.Threading.Tasks; 5 | 6 | namespace NHSCovidPassVerifier.Services.Repositories 7 | { 8 | public class JwkRepository : IJwkRepository 9 | { 10 | private readonly ISettingsService _settingsService; 11 | private IRestClient _restClient; 12 | 13 | public JwkRepository(ISettingsService settingsService, IRestClient restClient) 14 | { 15 | _settingsService = settingsService; 16 | _restClient = restClient; 17 | } 18 | 19 | public async Task> GetJwk() 20 | { 21 | return await _restClient.GetFileAsStreamAsync(_settingsService.GetJwkUrl); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Utils/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.ComponentModel; 5 | 6 | namespace NHSCovidPassVerifier.Utils 7 | { 8 | public static class Extensions 9 | { 10 | public static ObservableCollection ToObservableCollection(this IEnumerable col) 11 | { 12 | return new ObservableCollection(col); 13 | } 14 | public static string ToDescriptionString(this Enum val) 15 | { 16 | var attributes = (DescriptionAttribute[])val 17 | .GetType() 18 | .GetField(val.ToString()) 19 | .GetCustomAttributes(typeof(DescriptionAttribute), false); 20 | return attributes.Length > 0 ? attributes[0].Description : string.Empty; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/MockServices/MockConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Tests.MockServices 6 | { 7 | public class MockConfigurationProvider : IConfigurationProvider 8 | { 9 | public MockConfigurationProvider() { } 10 | 11 | public Stream GetConfiguration() 12 | { 13 | throw new System.NotImplementedException(); 14 | } 15 | 16 | public Stream GetCommonConfiguration() 17 | { 18 | return Assembly.GetExecutingAssembly().GetManifestResourceStream("NHSCovidPassVerifier.Tests.Resources.commonConfiguration.json"); 19 | } 20 | 21 | public string GetEnvironment() 22 | { 23 | throw new System.NotImplementedException(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Controls/Converters/DateTimeToResultFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using NHSCovidPassVerifier.Utils; 4 | using Xamarin.Forms; 5 | 6 | namespace NHSCovidPassVerifier.Controls.Converters 7 | { 8 | public class DateTimeToResultFormatConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var returnString = "Invalid DateTime"; 13 | 14 | if (value is DateTime input) 15 | returnString = input.FormatDateTime(); 16 | 17 | return returnString; 18 | } 19 | 20 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 21 | { 22 | return DateTime.Parse((string) value); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/FontSizeLabelEffect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.iOS; 3 | using UIKit; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Platform.iOS; 6 | 7 | [assembly: ResolutionGroupName("NHSCovidPassVerifier")] 8 | [assembly: ExportEffect(typeof(FontSizeLabelEffect), nameof(FontSizeLabelEffect))] 9 | namespace NHSCovidPassVerifier.iOS 10 | { 11 | public class FontSizeLabelEffect : PlatformEffect 12 | { 13 | protected override void OnAttached() 14 | { 15 | var label = (UILabel)Control; 16 | label.AdjustsFontSizeToFitWidth = true; 17 | label.Lines = 2; 18 | label.BaselineAdjustment = UIBaselineAdjustment.AlignCenters; 19 | label.LineBreakMode = UILineBreakMode.Clip; 20 | } 21 | 22 | protected override void OnDetached() 23 | { 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Controls/Converters/EpochDatetimeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace NHSCovidPassVerifier.Controls.Converters 6 | { 7 | public class EpochDatetimeConverter: DateTimeConverterBase 8 | { 9 | private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 10 | 11 | 12 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 13 | { 14 | if (reader.Value == null) { return null; } 15 | return Epoch.AddMilliseconds((long)reader.Value / 1000d); 16 | } 17 | 18 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 19 | { 20 | writer.WriteRawValue(((DateTime)value - Epoch).TotalMilliseconds + "000"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Utils/HyperlinkImage.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using Xamarin.Essentials; 6 | using Xamarin.Forms; 7 | 8 | namespace NHSCovidPassVerifier.Utils 9 | { 10 | public class HyperlinkImage : Image 11 | { 12 | public static readonly BindableProperty UrlProperty = BindableProperty.Create(nameof(Url), typeof(string), typeof(HyperlinkSpan), null); 13 | 14 | public string Url 15 | { 16 | get { return (string)GetValue(UrlProperty); } 17 | set { SetValue(UrlProperty, value); } 18 | } 19 | 20 | public HyperlinkImage() 21 | { 22 | GestureRecognizers.Add(new TapGestureRecognizer 23 | { 24 | Command = new AsyncCommand(async () => await Launcher.OpenAsync(Url)) 25 | }); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Enums/NhsColour.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | 4 | namespace NHSCovidPassVerifier.Utils 5 | { 6 | public enum NhsColour 7 | { 8 | NhsLinkColour, 9 | NhsErrorColour, 10 | 11 | NhsButtonColour, 12 | NhsButtonShadowColour, 13 | 14 | NhsBackgroundColour, 15 | NhsDarkBackground, 16 | 17 | NhsWhite, 18 | NhsBlue, 19 | NhsButtonGreen, 20 | NhsTextBlack, 21 | 22 | TextColourRed, 23 | BorderColour, 24 | BackGroundColour, 25 | } 26 | 27 | public static class NhsColourExtensions 28 | { 29 | public static Color Color(this NhsColour nhsColour) 30 | { 31 | string colourString = Enum.GetName(typeof(NhsColour), nhsColour); 32 | Color? colour = Application.Current.Resources[colourString] as Color?; 33 | return colour ?? Xamarin.Forms.Color.White; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Cose/HeaderParameterKey.cs: -------------------------------------------------------------------------------- 1 | using PeterO.Cbor; 2 | 3 | //MIT License 4 | //Copyright 2021 Myndigheten f�r digital f�rvaltning (DIGG) 5 | namespace NHSCovidPassVerifier.Models.Cose 6 | { 7 | 8 | //@author Henrik Bengtsson (extern.henrik.bengtsson@digg.se) 9 | //@author Martin Lindstr�m (martin@idsec.se) 10 | //@author Henric Norlander (extern.henric.norlander@digg.se) 11 | /// 12 | /// Representation of COSE header parameter keys. 13 | ///https://tools.ietf.org/html/rfc8152#section-3 14 | /// 15 | public class HeaderParameterKey 16 | { 17 | public static readonly CBORObject ALGORITHIM = CBORObject.FromObject(1); 18 | 19 | public static readonly CBORObject CRITICAL_HEADER = CBORObject.FromObject(2); 20 | 21 | public static readonly CBORObject CONTENT_TYPE = CBORObject.FromObject(3); 22 | 23 | public static readonly CBORObject KID = CBORObject.FromObject(4); 24 | } 25 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/Items/InternationalCertificateRecovery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace NHSCovidPassVerifier.Models.International.Items 5 | { 6 | public class InternationalCertificateRecovery 7 | { 8 | [JsonProperty("tg")] 9 | public string DiseaseTargeted { get; set; } 10 | 11 | [JsonProperty("fr")] 12 | public DateTime? DateOfFirstPositiveResult { get; set; } 13 | 14 | [JsonProperty("co")] 15 | public string CountryOfTest { get; set; } 16 | 17 | [JsonProperty("is")] 18 | public string CertificateIssuer { get; set; } 19 | 20 | [JsonProperty("df")] 21 | public DateTime? DateValidFrom { get; set; } 22 | 23 | [JsonProperty("du")] 24 | public DateTime? DateValidUntil { get; set; } 25 | 26 | [JsonProperty("ci")] 27 | public string CertificateId { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Utils/HyperlinkSpan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Models.Commands; 3 | using Xamarin.Essentials; 4 | using Xamarin.Forms; 5 | 6 | namespace NHSCovidPassVerifier.Utils 7 | { 8 | public class HyperlinkSpan : Span 9 | { 10 | public static readonly BindableProperty UrlProperty = BindableProperty.Create(nameof(Url), typeof(string), typeof(HyperlinkSpan), null); 11 | 12 | public string Url 13 | { 14 | get { return (string)GetValue(UrlProperty); } 15 | set { SetValue(UrlProperty, value); } 16 | } 17 | 18 | public HyperlinkSpan() 19 | { 20 | TextDecorations = TextDecorations.Underline; 21 | TextColor = NhsColour.NhsLinkColour.Color(); 22 | GestureRecognizers.Add(new TapGestureRecognizer 23 | { 24 | Command = new AsyncCommand(async () => await Launcher.OpenAsync(Url)) 25 | }); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace NHSCovidPassVerifier.Services.Interfaces 4 | { 5 | public interface IConfigurationProvider 6 | { 7 | /// 8 | /// Gets the apps configuration file 9 | /// 10 | /// a Stream of the configuration files contents. 11 | public Stream GetConfiguration(); 12 | 13 | /// 14 | /// Gets the common configuration file, which contains mappings for the certificates. 15 | /// 16 | /// a Stream of the configuration files contents. 17 | public Stream GetCommonConfiguration(); 18 | 19 | /// 20 | /// Gets the environment the app was built for. 21 | /// 22 | /// a String representing which environment the app was built for. 23 | public string GetEnvironment(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | (Describe the problem here) 13 | **Describe the solution you'd like** 14 | 16 | (Describe the solution here) 17 | **Describe alternatives you've considered** 18 | 19 | (Describe alternative solutions here) 20 | **Additional context** 21 | 22 | (If applicable) 23 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/MockServices/MockSecureStorageService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Tests.MockServices 6 | { 7 | public class MockSecureStorageService : ISecureStorageService 8 | { 9 | private readonly IDictionary _mockSecureStorage = new Dictionary(); 10 | 11 | public Task GetSecureStorageAsync(string key) 12 | { 13 | return Task.FromResult(_mockSecureStorage.TryGetValue(key, out var value) ? value : default); 14 | } 15 | 16 | public Task SetSecureStorageAsync(string key, T value) 17 | { 18 | _mockSecureStorage[key] = value; 19 | return Task.CompletedTask; 20 | } 21 | 22 | public Task Clear(string key) 23 | { 24 | return Task.FromResult(_mockSecureStorage.Remove(key)); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/EuHcertV1Schema.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NHSCovidPassVerifier.Models.International.Items; 4 | using Newtonsoft.Json; 5 | 6 | namespace NHSCovidPassVerifier.Models.International 7 | { 8 | public class EuHcertV1Schema 9 | { 10 | [JsonProperty("v")] 11 | public List Vaccinations { get; set; } 12 | 13 | [JsonProperty("r")] 14 | public List Recovery { get; set; } 15 | 16 | [JsonProperty("t")] 17 | public List TestResults { get; set; } 18 | 19 | [JsonProperty("dob")] 20 | public DateTime? DateOfBirth { get; set; } 21 | [JsonProperty("nam")] 22 | public InternationalCertificateSubject InternationalCertificateSubject { get; set; } 23 | [JsonProperty("ver")] 24 | public string Version { get; set; } 25 | 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/InternationalCertificatePayload.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Controls.Converters; 3 | using NHSCovidPassVerifier.Enums; 4 | using NHSCovidPassVerifier.Models.Interfaces; 5 | using Newtonsoft.Json; 6 | 7 | namespace NHSCovidPassVerifier.Models.International 8 | { 9 | public class InternationalCertificatePayload : ICertificatePayload 10 | { 11 | [JsonProperty("1")] 12 | public string iss { get; set; } 13 | 14 | [JsonProperty("6")] 15 | public int iat { get; set; } 16 | 17 | [JsonProperty("4")] 18 | public int exp { get; set; } 19 | 20 | [JsonProperty("-260")] 21 | public HCertModel hcert { get; set; } 22 | 23 | public CertificateType GetCertificateType() 24 | { 25 | return CertificateType.International; 26 | } 27 | } 28 | 29 | public class HCertModel 30 | { 31 | [JsonProperty("1")] 32 | public EuHcertV1Schema euHcertV1Schema; 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/Helpers/InternationalResultCardDataTemplateSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Models.International.Cards; 3 | using Xamarin.Forms; 4 | 5 | namespace NHSCovidPassVerifier.Views.Elements.Helpers 6 | { 7 | public class InternationalResultCardDataTemplateSelector : DataTemplateSelector 8 | { 9 | public DataTemplate VaccinationCardTemplate { get; set; } 10 | public DataTemplate RecoveryCardTemplate { get; set; } 11 | public DataTemplate TestResultCardTemplate { get; set; } 12 | 13 | protected override DataTemplate OnSelectTemplate(object item, BindableObject container) 14 | { 15 | var type = item.GetType(); 16 | if (type == typeof(VaccinationCard)) return VaccinationCardTemplate; 17 | if (type == typeof(RecoveryCard)) return RecoveryCardTemplate; 18 | if (type == typeof(TestResultCard)) return TestResultCardTemplate; 19 | 20 | throw new ArgumentOutOfRangeException(nameof(type)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/ZLibService.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using Ionic.Zlib; 4 | 5 | namespace NHSCovidPassVerifier.Services 6 | { 7 | public class ZLibService : IZLibService 8 | { 9 | public byte[] DecompressData(byte[] compressedBytes) 10 | { 11 | using var outMemoryStream = new MemoryStream(); 12 | using var outZStream = new ZlibStream(outMemoryStream, CompressionMode.Decompress); 13 | using Stream inMemoryStream = new MemoryStream(compressedBytes); 14 | CopyStream(inMemoryStream, outZStream); 15 | return outMemoryStream.ToArray(); 16 | } 17 | 18 | private static void CopyStream(Stream input, Stream output) 19 | { 20 | var buffer = new byte[2000]; 21 | int len; 22 | while ((len = input.Read(buffer, 0, 2000)) > 0) 23 | { 24 | output.Write(buffer, 0, len); 25 | } 26 | output.Flush(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | [assembly: AssemblyTitle("NHSCovidPassVerifier.Android")] 7 | [assembly: AssemblyDescription("")] 8 | [assembly: AssemblyCompany("")] 9 | [assembly: AssemblyProduct("NHSCovidPassVerifier.Android")] 10 | [assembly: AssemblyCopyright("Copyright © 2014")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly: AssemblyVersion("1.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0")] 17 | 18 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)] 19 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] 20 | 21 | [assembly: UsesFeature("android.hardware.camera", Required = true)] 22 | [assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)] 23 | 24 | #if DEBUG 25 | [assembly: AssemblyConfiguration("local")] 26 | #else 27 | [assembly: AssemblyConfiguration("Production")] 28 | #endif 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 NHSx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/LocaleService.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using NHSCovidPassVerifier.Configuration; 3 | using I18NPortable; 4 | 5 | namespace NHSCovidPassVerifier.Services 6 | { 7 | //See nuget https://github.com/xleon/I18N-Portable 8 | public static class LocalesService 9 | { 10 | public static void Initialize() 11 | { 12 | if (I18N.Current?.Locale == null) 13 | { 14 | I18N.Current 15 | .SetNotFoundSymbol("$") // Optional: when a key is not found, it will appear as $key$ (defaults to "$") 16 | .SetFallbackLocale("en") // Optional but recommended: locale to load in case the system locale is not supported 17 | .AddLocaleReader(IoCContainer.Resolve(), ".json") //Use the json parser 18 | .Init(typeof(LocalesService).GetTypeInfo().Assembly); 19 | } 20 | 21 | SetInternationalization(); 22 | } 23 | 24 | public static void SetInternationalization() 25 | { 26 | I18N.Current.Locale = "en"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/ViewModels/Base/BaseBindableObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Reflection; 4 | using Xamarin.Forms; 5 | 6 | namespace NHSCovidPassVerifier.ViewModels.Base 7 | { 8 | public abstract class BaseBindableObject : BindableObject 9 | { 10 | public void RaisePropertyChanged(Expression> property) 11 | { 12 | var name = GetMemberInfo(property).Name; 13 | OnPropertyChanged(name); 14 | } 15 | 16 | private MemberInfo GetMemberInfo(Expression expression) 17 | { 18 | MemberExpression operand; 19 | LambdaExpression lambdaExpression = (LambdaExpression)expression; 20 | if (lambdaExpression.Body as UnaryExpression != null) 21 | { 22 | UnaryExpression body = (UnaryExpression)lambdaExpression.Body; 23 | operand = (MemberExpression)body.Operand; 24 | } 25 | else 26 | { 27 | operand = (MemberExpression)lambdaExpression.Body; 28 | } 29 | return operand.Member; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | (Write your description here) 13 | **Steps to reproduce the bug** 14 | 19 | - (Write your steps here in bullet point or numbered format here) 20 | **Expected behavior** 21 | 22 | (Write your expected behavior here) 23 | **Screenshots** 24 | 25 | (If applicable) 26 | 27 | **Smartphone the bug was produced on (please complete the following information):** 28 | 31 | (Write your device information here) 32 | 33 | **Additional Information** 34 | 35 | (If applicable) 36 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/UtilsTests/NhsColourTest.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Utils; 3 | using NUnit.Framework; 4 | using Xamarin.Forms; 5 | using Xamarin.Forms.Mocks; 6 | 7 | namespace NHSCovidPassVerifier.Tests.UtilsTests 8 | { 9 | public class NhsColourTest 10 | { 11 | [TestCase(NhsColour.NhsLinkColour, "#005eb8")] 12 | [TestCase(NhsColour.NhsErrorColour, "#d5281b")] 13 | [TestCase(NhsColour.NhsButtonColour, "#007f3b")] 14 | [TestCase(NhsColour.NhsButtonShadowColour, "#00401E")] 15 | [TestCase(NhsColour.NhsBackgroundColour, "#f0f4f5")] 16 | [TestCase(NhsColour.NhsDarkBackground, "#262626")] 17 | [TestCase(NhsColour.NhsWhite, "#ffffff")] 18 | [TestCase(NhsColour.NhsLinkColour, "#005eb8")] 19 | public void TestColourEnum(NhsColour actualColor, string resourceValue) 20 | { 21 | MockForms.Init(); 22 | Application.Current = new App(); 23 | 24 | Color actual = actualColor.Color(); 25 | 26 | Assert.AreEqual(Color.FromHex(resourceValue), actual); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/CustomRenderers/CustomScannerPageRenderer.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.iOS.CustomRenderers; 2 | using NHSCovidPassVerifier.Views; 3 | using Foundation; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using UIKit; 9 | using Xamarin.Forms; 10 | using Xamarin.Forms.Platform.iOS; 11 | 12 | [assembly: ExportRenderer(typeof(QRScannerPage), typeof(CustomScannerPageRenderer))] 13 | namespace NHSCovidPassVerifier.iOS.CustomRenderers 14 | { 15 | public class CustomScannerPageRenderer : PageRenderer 16 | { 17 | public override void ViewWillDisappear(bool animated) 18 | { 19 | base.ViewWillDisappear(animated); 20 | UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.Unknown)), new NSString("orientation")); 21 | } 22 | 23 | public override void ViewWillAppear(bool animated) 24 | { 25 | base.ViewWillDisappear(animated); 26 | UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.Portrait)), new NSString("orientation")); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultElements/ExpiredCode.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace NHSCovidPassVerifier.Views.Elements.ScannerResultElements 6 | { 7 | [XamlCompilation(XamlCompilationOptions.Compile)] 8 | public partial class ExpiredCode : Grid 9 | { 10 | public ExpiredCode() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) 16 | { 17 | base.OnPropertyChanged(propertyName); 18 | 19 | if (propertyName == ExpiredTextProperty.PropertyName) 20 | Expired.Text = ExpiredText; 21 | } 22 | 23 | public static readonly BindableProperty ExpiredTextProperty = 24 | BindableProperty.Create(nameof(ExpiredTextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 25 | 26 | public string ExpiredText 27 | { 28 | get => (string)GetValue(ExpiredTextProperty); 29 | set => SetValue(ExpiredTextProperty, value); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Services/AndroidDeeplinkingService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Threading.Tasks; 4 | using Android.Content; 5 | using NHSCovidPassVerifier.Services.Interfaces; 6 | using Plugin.CurrentActivity; 7 | 8 | namespace NHSCovidPassVerifier.Droid.Services 9 | { 10 | public class AndroidDeeplinkingService : IDeeplinkingService 11 | { 12 | public Task GoToAppSettings() 13 | { 14 | try 15 | { 16 | var intent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings); 17 | intent.AddFlags(ActivityFlags.NewTask); 18 | string package_name = "uk.gov.dhsc.healthrecord"; 19 | var uri = Android.Net.Uri.FromParts("package", package_name, null); 20 | intent.SetData(uri); 21 | CrossCurrentActivity.Current.AppContext.StartActivity(intent); 22 | } 23 | catch (Exception ex) 24 | { 25 | Debug.WriteLine($"Error attempting to deep-link to application settings: {ex}"); 26 | } 27 | 28 | return Task.CompletedTask; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/NhsHeader.xaml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 20 | 21 | 22 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Services/StatusBarService.cs: -------------------------------------------------------------------------------- 1 | using Android.OS; 2 | using NHSCovidPassVerifier.Droid; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | using NHSCovidPassVerifier.Utils; 5 | using Plugin.CurrentActivity; 6 | using Xamarin.Forms; 7 | using Xamarin.Forms.Platform.Android; 8 | 9 | [assembly: Dependency(typeof(StatusBarService))] 10 | namespace NHSCovidPassVerifier.Droid 11 | { 12 | public class StatusBarService : IStatusBarService 13 | { 14 | public StatusBarService() 15 | { 16 | } 17 | 18 | public void RemoveStatusBar() 19 | { 20 | } 21 | 22 | public void SetDefaultStatusBar() 23 | { 24 | SetStatusBarColor(NhsColour.NhsBlue.Color()); 25 | } 26 | 27 | public void SetStatusBarColor(Color color) 28 | { 29 | if (CrossCurrentActivity.Current?.Activity?.Window != null) 30 | { 31 | if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) 32 | { 33 | CrossCurrentActivity.Current.Activity.Window.SetStatusBarColor(color.ToAndroid()); 34 | } 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/ISettingsService.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Threading.Tasks; 3 | 4 | namespace NHSCovidPassVerifier.Services.Interfaces 5 | { 6 | public interface ISettingsService 7 | { 8 | public bool UseMockServices { get; set; } 9 | 10 | public string GetJwkUrl { get; } 11 | 12 | public string AndroidAppCenterKey { get; } 13 | 14 | public string iOSAppCenterKey { get; } 15 | 16 | public string AllowLandScapePortrait { get; } 17 | 18 | public string PreventLandscape { get; } 19 | 20 | public int DefaultTimeout { get; } 21 | 22 | public int ScannerResultShownDuration { get; } 23 | 24 | public int PressedToReleasedCloseInterval { get; } 25 | 26 | public int JwkValidForHours { get; } 27 | 28 | public bool IsScreenShotAllowed { get; } 29 | 30 | public string Jwk { get; } 31 | 32 | public JArray PublicKeys { get; } 33 | 34 | public string TermsAndConditionsAgreed { get; } 35 | 36 | public string InternationalEnabled { get; } 37 | 38 | public Task ClearAllSettings(); 39 | 40 | public string GetVersionNumber(); 41 | } 42 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultElements/ValidCode.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | 6 | namespace NHSCovidPassVerifier.Views.Elements.ScannerResultElements 7 | { 8 | [XamlCompilation(XamlCompilationOptions.Compile)] 9 | public partial class ValidCode : Grid 10 | { 11 | public ValidCode() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) 17 | { 18 | base.OnPropertyChanged(propertyName); 19 | 20 | if (propertyName == ValidStatusTextProperty.PropertyName) 21 | ValidStatus.Text = ValidStatusText; 22 | } 23 | 24 | public static readonly BindableProperty ValidStatusTextProperty = 25 | BindableProperty.Create(nameof(ValidStatusTextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 26 | 27 | public string ValidStatusText 28 | { 29 | get => (string)GetValue(ValidStatusTextProperty); 30 | set => SetValue(ValidStatusTextProperty, value); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Utils/DateUtils.cs: -------------------------------------------------------------------------------- 1 | using I18NPortable; 2 | using System; 3 | using System.Globalization; 4 | 5 | namespace NHSCovidPassVerifier.Utils 6 | { 7 | public static class DateUtils 8 | { 9 | private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 10 | public static string FormatDateTime(this DateTime date) 11 | { 12 | return date.ToString("d MMM yyyy 'at' HH\\:mm", CultureInfo.InvariantCulture); 13 | } 14 | public static string FormatDate(this DateTime date) 15 | { 16 | return date.ToString("d MMMM yyyy"); 17 | } 18 | public static DateTime? ConvertEpochToDate(this int date) 19 | { 20 | if(date == 0) return null; 21 | return epoch.AddSeconds(date); 22 | } 23 | 24 | public static string FormatTimeToMidnightMidday(DateTime time) => time.Hour switch 25 | { 26 | 0 when time.Minute == 0 => "MIDNIGHT_TEXT".Translate(), 27 | 12 when time.Minute == 0 => "MIDDAY_TEXT".Translate(), 28 | _ => time.ToString("h\\.mm") + (time.Hour > 12 ? "pm" : "am") 29 | }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Services/ConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using System.Linq; 3 | using System.IO; 4 | using System.Reflection; 5 | using NHSCovidPassVerifier.Services.Interfaces; 6 | 7 | namespace NHSCovidPassVerifier.Droid 8 | { 9 | public class ConfigurationProvider : IConfigurationProvider 10 | { 11 | private readonly string environmentVariable; 12 | 13 | public ConfigurationProvider() 14 | { 15 | var assembly = Assembly.GetExecutingAssembly(); 16 | 17 | var attributes = assembly.GetCustomAttributes(true); 18 | 19 | var config = attributes.OfType().FirstOrDefault(); 20 | 21 | environmentVariable = config?.Configuration; 22 | } 23 | 24 | public Stream GetConfiguration() 25 | { 26 | return Application.Context.Assets?.Open($"appsettings.json"); 27 | } 28 | 29 | public Stream GetCommonConfiguration() 30 | { 31 | return Application.Context.Assets?.Open("commonConfiguration.json"); 32 | } 33 | 34 | public string GetEnvironment() 35 | { 36 | return environmentVariable; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultElements/InvalidCode.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace NHSCovidPassVerifier.Views.Elements.ScannerResultElements 6 | { 7 | [XamlCompilation(XamlCompilationOptions.Compile)] 8 | public partial class InvalidCode : Grid 9 | { 10 | public InvalidCode() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) 16 | { 17 | base.OnPropertyChanged(propertyName); 18 | 19 | if (propertyName == InvalidStatusTextProperty.PropertyName) 20 | InvalidStatus.Text = InvalidStatusText; 21 | } 22 | 23 | public static readonly BindableProperty InvalidStatusTextProperty = 24 | BindableProperty.Create(nameof(InvalidStatusTextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 25 | 26 | public string InvalidStatusText 27 | { 28 | get => (string)GetValue(InvalidStatusTextProperty); 29 | set => SetValue(InvalidStatusTextProperty, value); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/ISecureStorageService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace NHSCovidPassVerifier.Services.Interfaces 4 | { 5 | public interface ISecureStorageService 6 | { 7 | /// 8 | /// Retrieves a value from SecureStorage. 9 | /// 10 | /// Key for finding a specific type of value in SecureStorage 11 | /// The value stored with the given key 12 | Task GetSecureStorageAsync(string key); 13 | 14 | /// 15 | /// Stores a value into SecureStorage. 16 | /// 17 | /// A key for finding the stored value 18 | /// The value to store. 19 | /// The Task status 20 | Task SetSecureStorageAsync(string key, TValue value); 21 | 22 | /// 23 | /// Deletes a value from SecureStorage. 24 | /// 25 | /// The key for the value to be deleted. 26 | /// True if successfull, false otherwise. 27 | Task Clear(string key); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/ErrorHandlers/SignatureVerificationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NHSCovidPassVerifier.Services.ErrorHandlers 4 | { 5 | public sealed class SignatureVerificationException : Exception 6 | { 7 | /// Initializes a new instance of the 8 | public SignatureVerificationException() 9 | { 10 | } 11 | 12 | /// Initializes a new instance of the 13 | /// The parameter is a 14 | /// text string. 15 | public SignatureVerificationException(string message) 16 | : base(message) 17 | { 18 | 19 | } 20 | 21 | /// Initializes a new instance of the 22 | /// message and inner exception. 23 | /// The parameter is a 24 | /// text string. 25 | /// The parameter is an Exception object. 26 | public SignatureVerificationException(string message, Exception innerException) 27 | : base(message, innerException) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IQrDecoderService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using NHSCovidPassVerifier.Models.Cose; 3 | using NHSCovidPassVerifier.Models.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Services.Interfaces 6 | { 7 | public interface IQrDecoderService 8 | { 9 | /// 10 | /// Checks the validity of the qr code. 11 | /// 12 | /// the raw contents of the qr code. 13 | /// true if the code is valid, otherwise false. 14 | Task ValidateQrCode(string qrCode); 15 | 16 | /// 17 | /// Generates a Domestic of international qr code object, depending on the qr code. 18 | /// 19 | /// A Certificate which implements the ICertificate Interface. 20 | ICertificate GenerateCertificateFromQrCode(); 21 | 22 | /// 23 | /// Retrieves a Generated Certificate. 24 | /// 25 | /// A Certificate which implements the ICertificate Interface. 26 | ICertificate GetDecodedCertificate(); 27 | 28 | 29 | CoseSign1Object DecodeToCose(string base45String); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Mocks/MockCommonSettingsService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Services.Mocks 6 | { 7 | public class MockCommonSettingsService : ICommonSettingsService 8 | { 9 | public IDictionary VaccineManufacturers { get; } = new Dictionary(); 10 | public IDictionary VaccineTypes { get; } = new Dictionary(); 11 | public IDictionary DiseasesTargeted { get; } = new Dictionary(); 12 | public IDictionary VaccineNames { get; } = new Dictionary(); 13 | public IDictionary ReadableVaccineNames { get; } = new Dictionary(); 14 | public IDictionary TestTypes { get; } = new Dictionary(); 15 | public IDictionary TestResults { get; } = new Dictionary(); 16 | public IEnumerable EnglishCertificateIssuers { get; } = Enumerable.Empty(); 17 | public IDictionary InternationalMinimumDoses { get; } = new Dictionary(); 18 | } 19 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/SplashActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Android.App; 8 | using Android.Content; 9 | using Android.OS; 10 | using Android.Runtime; 11 | using Android.Views; 12 | using Android.Widget; 13 | 14 | namespace NHSCovidPassVerifier.Droid 15 | { 16 | [Activity(Theme = "@style/NHSCovidPassVerifier.Splash", MainLauncher = true, NoHistory = true, Icon = "@mipmap/icon", 17 | RoundIcon = "@mipmap/icon_round")] 18 | public class SplashActivity : Activity 19 | { 20 | public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState) 21 | { 22 | base.OnCreate(savedInstanceState, persistentState); 23 | } 24 | 25 | protected override void OnResume() 26 | { 27 | base.OnResume(); 28 | 29 | Task startupWork = new Task(() => { SimulateStartup(); }); 30 | startupWork.Start(); 31 | } 32 | void SimulateStartup() 33 | { 34 | StartActivity(new Intent(Application.Context, typeof(MainActivity))); 35 | } 36 | public override void OnBackPressed() { } 37 | } 38 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/MockServices/MockCommonSettingsService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Services.Mocks 6 | { 7 | public class MockCommonSettingsService : ICommonSettingsService 8 | { 9 | public IDictionary VaccineManufacturers { get; } = new Dictionary(); 10 | public IDictionary VaccineTypes { get; } = new Dictionary(); 11 | public IDictionary DiseasesTargeted { get; } = new Dictionary(); 12 | public IDictionary VaccineNames { get; } = new Dictionary(); 13 | public IDictionary ReadableVaccineNames { get; } = new Dictionary(); 14 | public IDictionary TestTypes { get; } = new Dictionary(); 15 | public IDictionary TestResults { get; } = new Dictionary(); 16 | public IEnumerable EnglishCertificateIssuers { get; } = Enumerable.Empty(); 17 | public IDictionary InternationalMinimumDoses { get; } = new Dictionary(); 18 | } 19 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/Items/InternationalCertificateTestResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace NHSCovidPassVerifier.Models.International.Items 5 | { 6 | /// 7 | /// Dto for a test_entry in the EU DCC schema. 8 | /// 9 | public class InternationalCertificateTestResult 10 | { 11 | [JsonProperty("tg")] 12 | public string DiseaseTargeted { get; set; } 13 | 14 | [JsonProperty("tt")] 15 | public string TestType { get; set; } 16 | 17 | [JsonProperty("nm")] 18 | public string TestName { get; set; } 19 | 20 | [JsonProperty("ma")] 21 | public string TestManufacturer { get; set; } 22 | 23 | [JsonProperty("sc")] 24 | public DateTime? SampleCollectedTime { get; set; } 25 | 26 | [JsonProperty("tr")] 27 | public string TestResult { get; set; } 28 | 29 | [JsonProperty("tc")] 30 | public string TestCentre { get; set; } 31 | 32 | [JsonProperty("co")] 33 | public string CountryOfTest { get; set; } 34 | 35 | [JsonProperty("is")] 36 | public string CertificateIssuer { get; set; } 37 | 38 | [JsonProperty("ci")] 39 | public string CertificateId { get; set; } 40 | } 41 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Services/ConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Linq; 3 | using System.Reflection; 4 | using NHSCovidPassVerifier.Services.Interfaces; 5 | using Foundation; 6 | 7 | namespace NHSCovidPassVerifier.iOS 8 | { 9 | public class ConfigurationProvider : IConfigurationProvider 10 | { 11 | private readonly string environmentVariable; 12 | 13 | public ConfigurationProvider() 14 | { 15 | var assembly = Assembly.GetExecutingAssembly(); 16 | 17 | var attributes = assembly.GetCustomAttributes(true); 18 | 19 | var config = attributes.OfType().FirstOrDefault(); 20 | 21 | environmentVariable = config?.Configuration; 22 | } 23 | 24 | public Stream GetConfiguration() 25 | { 26 | var path = NSBundle.MainBundle.PathForResource($"appsettings.json", null); 27 | return File.OpenRead(path); 28 | } 29 | 30 | public Stream GetCommonConfiguration() 31 | { 32 | var path = NSBundle.MainBundle.PathForResource("commonConfiguration.json", null); 33 | return File.OpenRead(path); 34 | } 35 | 36 | public string GetEnvironment() 37 | { 38 | return environmentVariable; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/International/Items/InternationalCertificateVaccination.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace NHSCovidPassVerifier.Models.International.Items 5 | { 6 | /// 7 | /// Dto for a vaccination_entry in EU DCC schema. 8 | /// "lot" does not exist in the schema and has been added. 9 | /// 10 | public class InternationalCertificateVaccination 11 | { 12 | [JsonProperty("tg")] 13 | public string DiseaseTargeted { get; set; } 14 | 15 | [JsonProperty("vp")] 16 | public string VaccineTypeCode { get; set; } 17 | 18 | [JsonProperty("mp")] 19 | public string ProductCode { get; set; } 20 | 21 | [JsonProperty("ma")] 22 | public string Manufacturer { get; set; } 23 | 24 | [JsonProperty("dn")] 25 | public int DoseNumber { get; set; } 26 | 27 | [JsonProperty("sd")] 28 | public int TotalNumberOfDose { get; set; } 29 | 30 | [JsonProperty("dt")] 31 | public DateTime? DateOfVaccination { get; set; } 32 | 33 | [JsonProperty("co")] 34 | public string Country { get; set; } 35 | 36 | [JsonProperty("is")] 37 | public string CertificateIssuer { get; set; } 38 | 39 | [JsonProperty("ci")] 40 | public string CertificateId { get; set; } 41 | 42 | } 43 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IQrValidatorService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using NHSCovidPassVerifier.Models; 4 | using NHSCovidPassVerifier.Models.Cose; 5 | 6 | namespace NHSCovidPassVerifier.Services.Interfaces 7 | { 8 | public interface IQrValidatorService 9 | { 10 | /// 11 | /// Checks the validity of a Domestic qr code. 12 | /// 13 | /// 14 | /// 15 | /// key for finding the correct public key. 16 | /// 17 | public Task ValidateQrCodeForDomesticCertificate(byte[] digest, byte[] signature, string keyId); 18 | 19 | /// 20 | /// Checks the validity of a International qr code. 21 | /// 22 | /// 23 | /// 24 | public Task ValidateQrCodeForInternationalCertificate(CoseSign1Object coseSign1Object); 25 | 26 | /// 27 | /// Gets an IEnumerable of public keys for checking qr codes. 28 | /// 29 | /// 30 | /// 31 | Task> GetKeyVaultKey(string id = null); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Interfaces/IJwkService.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models; 2 | using NHSCovidPassVerifier.Models.Dtos; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NHSCovidPassVerifier.Services.Interfaces 9 | { 10 | public interface IJwkService 11 | { 12 | /// 13 | /// Attempts to get the jwk from the apps jwkurl. 14 | /// 15 | /// A NhsAppResult with the JwkDto or empty if it fails. 16 | Task> GetJwk(); 17 | 18 | /// 19 | /// Attempts to update the Jwk from the jwkurl, the jwk is saved to SecureStorage. 20 | /// 21 | /// boolean true if jwk was updated, false if it failed. 22 | Task UpdateJwkList(); 23 | 24 | /// 25 | /// Checks if the jwk needs to be updated. 26 | /// 27 | /// true if jwk is older than the jwkvalidfor config setting, otherwise false. 28 | Task JwkListNeedsUpdating(); 29 | 30 | /// 31 | /// Check if there is a jwk object in SecureStorage. 32 | /// 33 | /// true if jwkList is present, otherwise false. 34 | Task JwkListPresent(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/LandingViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.ViewModels; 4 | using I18NPortable; 5 | using Moq; 6 | using NUnit.Framework; 7 | 8 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 9 | { 10 | [TestFixture] 11 | public class LandingViewModelTests 12 | { 13 | private readonly LandingViewModel _viewModel; 14 | private Mock> _secureStorageService; 15 | 16 | private const string ExpectedImageSource = "nhs_logo_white.png"; 17 | 18 | public LandingViewModelTests() 19 | { 20 | _secureStorageService = new Mock>(); 21 | _viewModel = new LandingViewModel(_secureStorageService.Object); 22 | } 23 | 24 | [Test] 25 | public void ImageIsInitialised() 26 | { 27 | Assert.AreEqual(ExpectedImageSource, _viewModel.LandingsPageImageSource); 28 | } 29 | 30 | [Test] 31 | public void TextIsCorrect() 32 | { 33 | Assert.AreEqual(_viewModel.OpenScannerText, "LANDING_PAGE_QR_CODE".Translate()); 34 | } 35 | 36 | [Test] 37 | public void CommandIsInitialised() 38 | { 39 | Assert.IsNotNull(_viewModel.NextPageCommand); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/ApprovePageViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.Tests.MockServices; 4 | using NHSCovidPassVerifier.ViewModels; 5 | using I18NPortable; 6 | using Moq; 7 | using NUnit.Framework; 8 | 9 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 10 | { 11 | [TestFixture] 12 | public class ApprovePageViewModelTests 13 | { 14 | private readonly ApprovePageViewModel _viewModel; 15 | 16 | public ApprovePageViewModelTests() 17 | { 18 | IoCContainer.RegisterSingleton(); 19 | var mockLoggingService = new Mock().Object; 20 | _viewModel = new ApprovePageViewModel(mockLoggingService); 21 | } 22 | 23 | [Test] 24 | public void TextIsCorrect() 25 | { 26 | Assert.AreEqual(_viewModel.ApprovePageTitle, "APPROVE_TITLE".Translate()); 27 | Assert.AreEqual(_viewModel.ApproveToCText, "APPROVE_TEXT".Translate()); 28 | Assert.AreEqual(_viewModel.ToCLinkText, "APPROVE_TERMS_AND_CONDITIONS_TEXT".Translate()); 29 | Assert.AreEqual(_viewModel.ApproveToCText_2, "APPROVE_TEXT_2".Translate()); 30 | Assert.AreEqual(_viewModel.AcceptButtonText, "TERMS_AND_CONDITIONS_ACCEPT_TEXT".Translate()); 31 | 32 | } 33 | 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/MenuItem.xaml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 36 | 37 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/UtilsTests/Asn1UtilsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Models.Cose; 3 | using NHSCovidPassVerifier.Services.Utils; 4 | using NHSCovidPassVerifier.Utils; 5 | using I18NPortable; 6 | using NUnit.Framework; 7 | using PeterO.Cbor; 8 | 9 | namespace NHSCovidPassVerifier.Tests.UtilsTests 10 | { 11 | public class Asn1UtilsTests 12 | { 13 | [TestCase((byte)0x02 , 2)] 14 | [TestCase((byte)0x22, 34)] 15 | public void TestToUnsignedInteger(byte inputByte, int Result) 16 | { 17 | //Given 18 | byte[] bytes = new byte[] { 19 | inputByte, 20 | }; 21 | 22 | //When 23 | var returnedArray = Asn1Utils.ToUnsignedInteger(bytes); 24 | 25 | //Then 26 | Assert.AreEqual(returnedArray[0], 2); 27 | Assert.AreEqual(returnedArray[1], 1); 28 | Assert.AreEqual(returnedArray[2], Result); 29 | } 30 | 31 | [TestCase(0)] 32 | public void TestToUnsignedIntegerEmptyArray( int Result) 33 | { 34 | //Given 35 | byte[] bytes = new byte[] { 36 | 37 | }; 38 | 39 | //When 40 | var returnedArray = Asn1Utils.ToUnsignedInteger(bytes); 41 | 42 | //Then 43 | Assert.AreEqual(returnedArray[0], 2); 44 | Assert.AreEqual(returnedArray[1], 1); 45 | Assert.AreEqual(returnedArray[2], Result); 46 | } 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultEntry.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerVaccinationResultEntry.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/MockServices/MockSettingsService.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Services.Interfaces; 2 | using Newtonsoft.Json.Linq; 3 | using System.Threading.Tasks; 4 | 5 | namespace NHSCovidPassVerifier.Tests.MockServices 6 | { 7 | public class MockSettingsService : ISettingsService 8 | { 9 | public MockSettingsService() 10 | { 11 | UseMockServices = true; 12 | } 13 | 14 | public bool UseMockServices { get; set; } 15 | 16 | public string GetJwkUrl => ""; 17 | 18 | public string AndroidAppCenterKey => ""; 19 | 20 | public string iOSAppCenterKey => ""; 21 | 22 | public string AllowLandScapePortrait => nameof(AllowLandScapePortrait); 23 | 24 | public string PreventLandscape => nameof(PreventLandscape); 25 | 26 | public int DefaultTimeout => 15; 27 | 28 | public int ScannerResultShownDuration => 3000; 29 | 30 | public int PressedToReleasedCloseInterval => 100; 31 | 32 | public int JwkValidForHours => 6; 33 | 34 | public bool IsScreenShotAllowed => true; 35 | 36 | public string Jwk => ""; 37 | public JArray PublicKeys { get; } 38 | 39 | public string TermsAndConditionsAgreed => nameof(TermsAndConditionsAgreed); 40 | 41 | public string InternationalEnabled => nameof(InternationalEnabled); 42 | 43 | public Task ClearAllSettings() 44 | { 45 | return Task.CompletedTask; 46 | } 47 | public string GetVersionNumber() 48 | { 49 | return "1.2.0"; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/FAQViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.ViewModels; 2 | using I18NPortable; 3 | using NUnit.Framework; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 9 | { 10 | [TestFixture] 11 | public class FAQViewModelTests 12 | { 13 | private readonly FAQViewModel _viewModel; 14 | public FAQViewModelTests() 15 | { 16 | _viewModel = new FAQViewModel(); 17 | } 18 | 19 | [Test] 20 | public void TextIsInitializedCorrectly() 21 | { 22 | Assert.AreEqual("FAQ_COMMON_QUESTIONS_TITLE".Translate(), _viewModel.commonQuestionsTitle); 23 | Assert.AreEqual("FAQ_INVALIDQR_QUESTION".Translate(), _viewModel.InvalidQRCodeQuestion); 24 | Assert.AreEqual("FAQ_INVALIDQR_ANSWER".Translate(), _viewModel.InvalidQRCodeAnswer); 25 | Assert.AreEqual("FAQ_INTERNET_QUESTION".Translate(), _viewModel.InternetQuestion); 26 | Assert.AreEqual("FAQ_INTERNET_ANSWER".Translate(), _viewModel.InternetAnswer); 27 | Assert.AreEqual("FAQ_INTERNATIONAL_QUESTION".Translate(), _viewModel.InternationalQuestion); 28 | Assert.AreEqual("FAQ_INTERNATIONAL_ANSWER".Translate(), _viewModel.InternationalAnswer); 29 | Assert.AreEqual("FAQ_MINIMUM_REQUIREMENT_QUESTION".Translate(), _viewModel.MinimumRequirementsQuestion); 30 | Assert.AreEqual("FAQ_MINIMUM_REQUIREMENT_ANSWER".Translate(), _viewModel.MinimumRequirementsAnswer); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/MockServices/MockNavigationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | using Xamarin.Forms; 5 | 6 | namespace NHSCovidPassVerifier.Tests.MockServices 7 | { 8 | public class MockNavigationService : INavigationService 9 | { 10 | public Task PopPageWithResult(bool animated = true, object data = null) 11 | { 12 | return Task.CompletedTask; 13 | } 14 | 15 | public Task ReplaceTopPage(Page pageToPush, bool animated = true, object data = null) 16 | { 17 | return Task.CompletedTask; 18 | } 19 | 20 | public Task GoToErrorPage(string title = null, string description = null, string buttonText = null, Func buttonCallback = null) 21 | { 22 | return Task.CompletedTask; 23 | } 24 | 25 | public void OpenLandingPage() 26 | { 27 | } 28 | 29 | public Task PopPage(bool animated) 30 | { 31 | return Task.CompletedTask; 32 | } 33 | 34 | public Task PopPage() 35 | { 36 | return Task.CompletedTask; 37 | } 38 | 39 | public Task PushModal(Page page, bool animated = true, object data = null) 40 | { 41 | return Task.CompletedTask; 42 | } 43 | 44 | public Task PushPage(Page page, bool animated = true, object data = null) 45 | { 46 | return Task.CompletedTask; 47 | } 48 | 49 | public Page FindCurrentPage() 50 | { 51 | throw new NotImplementedException(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/InternationalEnabledService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using NHSCovidPassVerifier.Models.International; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | 5 | namespace NHSCovidPassVerifier.Services 6 | { 7 | public class InternationalEnabledService : IInternationalEnabledService 8 | { 9 | private bool _internationalEnabled; 10 | 11 | private readonly ISecureStorageService _secureStorageService; 12 | private readonly ISettingsService _settingsService; 13 | 14 | public InternationalEnabledService(ISecureStorageService secureStorageService, 15 | ISettingsService settingsService) 16 | { 17 | _secureStorageService = secureStorageService; 18 | _settingsService = settingsService; 19 | UpdateInternationalEnabled(); 20 | } 21 | 22 | private async Task UpdateInternationalEnabled() 23 | { 24 | _internationalEnabled = 25 | (await _secureStorageService.GetSecureStorageAsync(_settingsService.InternationalEnabled)) 26 | ?.IsInternationalEnabled ?? false; 27 | } 28 | 29 | public bool GetInternationalEnabled() 30 | { 31 | return _internationalEnabled; 32 | } 33 | 34 | public async Task SetInternationalEnabled(bool newValue) 35 | { 36 | _internationalEnabled = newValue; 37 | await _secureStorageService.SetSecureStorageAsync(_settingsService.InternationalEnabled, 38 | new InternationalEnabled { IsInternationalEnabled = newValue }); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/MenuItem.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Windows.Input; 3 | using Xamarin.Forms; 4 | using Xamarin.Forms.Xaml; 5 | 6 | namespace NHSCovidPassVerifier.Views.Elements 7 | { 8 | [XamlCompilation(XamlCompilationOptions.Compile)] 9 | public partial class MenuItem : Grid 10 | { 11 | public MenuItem() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) 17 | { 18 | base.OnPropertyChanged(propertyName); 19 | 20 | if (propertyName == TextProperty.PropertyName) 21 | { 22 | TextLabel.Text = Text; 23 | } 24 | else if (propertyName == CommandProperty.PropertyName) 25 | { 26 | CommandGestureRecognizer.Command = Command; 27 | } 28 | } 29 | 30 | public static readonly BindableProperty TextProperty = 31 | BindableProperty.Create(nameof(TextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 32 | 33 | public string Text 34 | { 35 | get => (string)GetValue(TextProperty); 36 | set => SetValue(TextProperty, value); 37 | } 38 | 39 | public static readonly BindableProperty CommandProperty = 40 | BindableProperty.Create(nameof(CommandProperty), typeof(ICommand), typeof(Grid), null, BindingMode.OneWay); 41 | 42 | public ICommand Command 43 | { 44 | get => (ICommand)GetValue(CommandProperty); 45 | set => SetValue(CommandProperty, value); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/NHSCovidPassVerifier.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | ;Debug 9 | 10 | 11 | 12 | 13 | Always 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | runtime; build; native; contentfiles; analyzers; buildtransitive 28 | all 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/UtilsTests/SetDashIfNoValueUtilTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Utils; 3 | using I18NPortable; 4 | using NUnit.Framework; 5 | 6 | namespace NHSCovidPassVerifier.Tests.UtilsTests 7 | { 8 | public class SetDashIfNoValueUtilTests 9 | { 10 | 11 | [TestCase("TestString")] 12 | [TestCase("Test String")] 13 | [TestCase("T")] 14 | public void TestSetDashIfNoValueString(string expected) 15 | { 16 | //given 17 | var returnedValue = SetDashIfNoValueUtil.SetDashIfNoValue(expected); 18 | 19 | //When 20 | Assert.AreEqual(expected, returnedValue); 21 | 22 | } 23 | 24 | [TestCase("01/08/2021 14:00:00")] 25 | [TestCase("12/25/2021 14:00:00")] 26 | [TestCase("01/01/2021 23:59:59")] 27 | public void TestSetDashIfNoValueDate(DateTime InputDate) 28 | { 29 | //Given 30 | var returnedValue = SetDashIfNoValueUtil.SetDashIfNoValue(InputDate); 31 | 32 | //When 33 | var expected = DateUtils.FormatDate(InputDate); 34 | 35 | //Then 36 | Assert.AreEqual(expected, returnedValue); 37 | 38 | } 39 | 40 | [TestCase("")] 41 | public void TestSetDashIfNoValueEmptyString(string expected) 42 | { 43 | //given 44 | var returnedValue = SetDashIfNoValueUtil.SetDashIfNoValue(expected); 45 | 46 | //When 47 | expected = "-"; 48 | 49 | //Then 50 | Assert.AreEqual(expected, returnedValue); 51 | Assert.AreEqual(expected.Translate(), returnedValue.Translate()); 52 | 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/ViewModels/FAQViewModel.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.ViewModels.Base; 2 | using I18NPortable; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace NHSCovidPassVerifier.ViewModels 8 | { 9 | public class FAQViewModel : BaseViewModel 10 | { 11 | public string commonQuestionsTitle { get; set; } 12 | public string InvalidQRCodeQuestion { get; private set; } 13 | public string InvalidQRCodeAnswer { get; set; } 14 | public string InternetQuestion { get; private set; } 15 | public string InternetAnswer { get; private set; } 16 | public string InternationalQuestion { get; private set; } 17 | public string InternationalAnswer { get; private set; } 18 | public string MinimumRequirementsQuestion { get; private set; } 19 | public string MinimumRequirementsAnswer { get; private set; } 20 | 21 | public FAQViewModel() 22 | { 23 | InitText(); 24 | } 25 | 26 | private void InitText() 27 | { 28 | commonQuestionsTitle = "FAQ_COMMON_QUESTIONS_TITLE".Translate(); 29 | InvalidQRCodeQuestion = "FAQ_INVALIDQR_QUESTION".Translate(); 30 | InvalidQRCodeAnswer = "FAQ_INVALIDQR_ANSWER".Translate(); 31 | InternetQuestion = "FAQ_INTERNET_QUESTION".Translate(); 32 | InternetAnswer = "FAQ_INTERNET_ANSWER".Translate(); 33 | InternationalQuestion = "FAQ_INTERNATIONAL_QUESTION".Translate(); 34 | InternationalAnswer = "FAQ_INTERNATIONAL_ANSWER".Translate(); 35 | MinimumRequirementsQuestion = "FAQ_MINIMUM_REQUIREMENT_QUESTION".Translate(); 36 | MinimumRequirementsAnswer = "FAQ_MINIMUM_REQUIREMENT_ANSWER".Translate(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/QrScannerViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models.International; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.ViewModels; 4 | using I18NPortable; 5 | using Moq; 6 | using NUnit.Framework; 7 | 8 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 9 | { 10 | [TestFixture] 11 | class QrScannerViewModelTests 12 | { 13 | private readonly QRScannerViewModel _viewModel; 14 | 15 | private readonly IQrDecoderService _qrDecoderService; 16 | private readonly ILoggingService _loggingService; 17 | private readonly IJwkService _jwkService; 18 | private readonly IInternationalEnabledService _internationalEnabledService; 19 | private readonly ICommonSettingsService _commonSettingsService; 20 | 21 | public QrScannerViewModelTests() 22 | { 23 | _qrDecoderService = new Mock().Object; 24 | _loggingService = new Mock().Object; 25 | _jwkService = new Mock().Object; 26 | _internationalEnabledService = new Mock().Object; 27 | _commonSettingsService = new Mock().Object; 28 | 29 | _viewModel = new QRScannerViewModel(_qrDecoderService, _loggingService, _jwkService, _internationalEnabledService, _commonSettingsService); 30 | } 31 | 32 | [Test] 33 | public void TestTextIsCorrect() 34 | { 35 | Assert.AreEqual("NHS_COVID_STATUS".Translate(), this._viewModel.CovidStatus); 36 | } 37 | 38 | [Test] 39 | public void TestCommandsHaveBeenInitialised() 40 | { 41 | Assert.IsNotNull(this._viewModel.BackCommand); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultElements/ExpiresDateTimeText.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace NHSCovidPassVerifier.Views.Elements.ScannerResultElements 6 | { 7 | [XamlCompilation(XamlCompilationOptions.Compile)] 8 | public partial class ExpiresDateTimeText : Grid 9 | { 10 | public ExpiresDateTimeText() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) 16 | { 17 | base.OnPropertyChanged(propertyName); 18 | 19 | if (propertyName == ExpiresDateTextProperty.PropertyName) 20 | ExpiresDate.Text = ExpiresDateText; 21 | 22 | else if (propertyName == ExpiresTimeTextProperty.PropertyName) 23 | ExpiresTime.Text = ExpiresTimeText; 24 | 25 | } 26 | 27 | public static readonly BindableProperty ExpiresDateTextProperty = 28 | BindableProperty.Create(nameof(ExpiresDateTextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 29 | 30 | public string ExpiresDateText 31 | { 32 | get => (string)GetValue(ExpiresDateTextProperty); 33 | set => SetValue(ExpiresDateTextProperty, value); 34 | } 35 | 36 | public static readonly BindableProperty ExpiresTimeTextProperty = 37 | BindableProperty.Create(nameof(ExpiresTimeTextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 38 | 39 | public string ExpiresTimeText 40 | { 41 | get => (string)GetValue(ExpiresTimeTextProperty); 42 | set => SetValue(ExpiresTimeTextProperty, value); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/AboutPageExpander.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Input; 8 | using Xamarin.Forms; 9 | using Xamarin.Forms.Xaml; 10 | 11 | namespace NHSCovidPassVerifier.Views.Elements 12 | { 13 | [XamlCompilation(XamlCompilationOptions.Compile)] 14 | public partial class AboutPageExpander : Frame 15 | { 16 | public AboutPageExpander() 17 | { 18 | InitializeComponent(); 19 | } 20 | 21 | protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) 22 | { 23 | base.OnPropertyChanged(propertyName); 24 | 25 | if (propertyName == TextProperty.PropertyName) 26 | { 27 | TextLabel.Text = Text; 28 | } 29 | else if (propertyName == TextTitleProperty.PropertyName) 30 | { 31 | TextTitleLabel.Text = TextTitle; 32 | } 33 | } 34 | 35 | public static readonly BindableProperty TextProperty = 36 | BindableProperty.Create(nameof(TextProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 37 | 38 | public string Text 39 | { 40 | get => (string)GetValue(TextProperty); 41 | set => SetValue(TextProperty, value); 42 | } 43 | 44 | public static readonly BindableProperty TextTitleProperty = 45 | BindableProperty.Create(nameof(TextTitleProperty), typeof(string), typeof(Grid), null, BindingMode.OneWay); 46 | 47 | public string TextTitle 48 | { 49 | get => (string)GetValue(TextTitleProperty); 50 | set => SetValue(TextTitleProperty, value); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultElements/ExpiresDateTimeText.xaml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/TestData/InternationalCardData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NHSCovidPassVerifier.Models; 4 | using NHSCovidPassVerifier.Models.International; 5 | using NHSCovidPassVerifier.Models.International.Cards; 6 | using NHSCovidPassVerifier.Models.International.Items; 7 | 8 | namespace NHSCovidPassVerifier.Tests.TestData 9 | { 10 | public static class InternationalCardData 11 | { 12 | public static DateTime refDate = DateTime.UtcNow; 13 | 14 | 15 | public static TestResultCard GetTestResultCard() 16 | { 17 | 18 | var testCertificate = new InternationalCertificateTestResult() 19 | { 20 | TestName = "PCR" 21 | 22 | 23 | }; 24 | 25 | return new TestResultCard(testCertificate); 26 | 27 | } 28 | 29 | public static TestResultCard GetEmptyTestResultCard() 30 | { 31 | 32 | var testCertificate = new InternationalCertificateTestResult() 33 | { 34 | TestName = "PCR" 35 | 36 | }; 37 | 38 | return new TestResultCard(testCertificate); 39 | 40 | } 41 | 42 | public static VaccinationCard GetVaccinationCard() 43 | { 44 | 45 | var testVaccinationCertificate = new InternationalCertificateVaccination 46 | { 47 | DiseaseTargeted = "COVID-19" 48 | 49 | }; 50 | 51 | return new VaccinationCard(testVaccinationCertificate); 52 | 53 | } 54 | 55 | public static RecoveryCard GetRecoveryCard() 56 | { 57 | 58 | var testRecoveryCertificate = new InternationalCertificateRecovery 59 | { 60 | DiseaseTargeted = "COVID-19" 61 | 62 | }; 63 | 64 | return new RecoveryCard(testRecoveryCertificate); 65 | 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/ViewModels/ApprovePageViewModel.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models.Commands; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.ViewModels.Base; 4 | using I18NPortable; 5 | using System.Threading.Tasks; 6 | using System.Windows.Input; 7 | using NHSCovidPassVerifier.Models.Logging; 8 | 9 | namespace NHSCovidPassVerifier.ViewModels 10 | { 11 | public class ApprovePageViewModel : BaseViewModel 12 | { 13 | private readonly ILoggingService _loggingService; 14 | 15 | public string ApprovePageTitle { get; set; } 16 | public string ApproveToCText { get; set; } 17 | public string ToCLinkText { get; set; } 18 | public string ApproveToCText_2 { get; set; } 19 | public string AcceptButtonText { get; set; } 20 | 21 | public ICommand AgreeCommand => new AsyncCommand(async () => await ExecuteOnceAsync(EnableInternational)); 22 | public override ICommand BackCommand => BackWithResultCommand; 23 | 24 | public ApprovePageViewModel(ILoggingService loggingService) 25 | { 26 | _loggingService = loggingService; 27 | 28 | InitText(); 29 | } 30 | 31 | private void InitText() 32 | { 33 | ApprovePageTitle = "APPROVE_TITLE".Translate(); 34 | ApproveToCText = "APPROVE_TEXT".Translate(); 35 | ToCLinkText = "APPROVE_TERMS_AND_CONDITIONS_TEXT".Translate(); 36 | ApproveToCText_2 = "APPROVE_TEXT_2".Translate(); 37 | AcceptButtonText = "TERMS_AND_CONDITIONS_ACCEPT_TEXT".Translate(); 38 | } 39 | 40 | private async Task EnableInternational() 41 | { 42 | await InnerToggleInternational(true); 43 | _loggingService.LogMessage(LogSeverity.INFO, "International Enabled"); 44 | await _navigationService.PopPage(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | ## How to contribute to NHS COVID Pass Verifier 2 | 3 | #### Did you find a bug? 4 | If the bug is a security vulnerability issue, **Do not open up a github issue**, instead refer to the [COVID Pass vulnerability disclosure policy.](https://www.nhsx.nhs.uk/covid-19-response/covid-19-vaccination-status-vulnerability-disclosure-policy/) 5 | 6 | If you have found a bug, please ensure it hasn't been reported already under [Issues.](https://github.com/ukhsa-collaboration/covid-pass-verifier/issues) 7 | 8 | If you're unable to find an open issue addressing the problem, [open a new one.](https://github.com/ukhsa-collaboration/covid-pass-verifier/issues/new) Be sure to include a **title and clear description**, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring. 9 | 10 | #### Contributing 11 | This is the process for submitting proposed changes to the NHS COVID Pass Verifier repository: 12 | 13 | 1. Create an appropriatley named branch. 14 | 2. Make the changes. 15 | 3. Open a Pull Request from your branch into the **Main** Branch. 16 | 4. The team will review the Pull Request, to decide if the change should be included. 17 | 5. If the team agrees on the proposed change, it will get approved and merged. 18 | 19 | #### Do you have any questions about the NHS COVID Pass Verifier? 20 | 21 | If you have any questions about the NHS COVID Pass Verifier please email covid-status.feedback@nhs.net 22 | 23 | ## Coding Standards 24 | **Git Branches** should be camel cased with key information on what is the purpose of the branch, prefixed with "bugfix/". For example, fixing a bug related to the help button, should be similiar to "bugfix/help_button_about_page". 25 | 26 | If developing on the NHS COVID Pass Verifier application, please follow the Coding Conventions here: https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions 27 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Services/Repositories/SecureStorageService.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models.Logging; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using Newtonsoft.Json; 4 | using System; 5 | using System.Threading.Tasks; 6 | using Xamarin.Essentials; 7 | 8 | namespace NHSCovidPassVerifier.Services.Repositories 9 | { 10 | public class SecureStorageService : ISecureStorageService 11 | { 12 | private readonly ILoggingService _loggingService; 13 | 14 | public SecureStorageService(ILoggingService loggingService) 15 | { 16 | _loggingService = loggingService; 17 | } 18 | 19 | public async Task GetSecureStorageAsync(string key) 20 | { 21 | try 22 | { 23 | var store = await SecureStorage.GetAsync(key); 24 | 25 | return store != default ? JsonConvert.DeserializeObject(store) : default(TValue); 26 | } 27 | catch (Exception e) 28 | { 29 | _loggingService.LogException(LogSeverity.ERROR, e, $"Error[{nameof(SecureStorage)}] Error Getting Key {key} in {nameof(GetSecureStorageAsync)}"); 30 | 31 | throw; 32 | } 33 | } 34 | 35 | public async Task SetSecureStorageAsync(string key, TValue value) 36 | { 37 | try 38 | { 39 | await SecureStorage.SetAsync(key, JsonConvert.SerializeObject(value)); 40 | } 41 | catch (Exception e) 42 | { 43 | _loggingService.LogException(LogSeverity.ERROR, e, $"Error[{nameof(SecureStorage)}] Error Setting Key {key} in {nameof(SetSecureStorageAsync)}"); 44 | 45 | throw; 46 | } 47 | } 48 | 49 | public async Task Clear(string key) 50 | { 51 | return await Task.FromResult(SecureStorage.Remove(key)); 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 28 | 29 | 32 | 33 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Android/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. 51 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ServicesTests/RepositoriesTests/QrECValidatorServiceTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models.Dtos; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.Services.Repositories; 4 | using NHSCovidPassVerifier.Tests.TestData; 5 | using Microsoft.IdentityModel.Tokens; 6 | using Moq; 7 | using Newtonsoft.Json; 8 | using NUnit.Framework; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Security.Cryptography; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using NHSCovidPassVerifier.Models; 15 | using NHSCovidPassVerifier.Services; 16 | 17 | namespace NHSCovidPassVerifier.Tests.RepositoryTests 18 | { 19 | [TestFixture] 20 | class QrECValidatorServiceTests 21 | { 22 | private readonly Mock> _mockSecureStorage; 23 | private readonly Mock _mockLoggingService; 24 | private readonly IQrValidatorService _qrValidatorService; 25 | private readonly ISettingsService settingsService; 26 | 27 | public QrECValidatorServiceTests() 28 | { 29 | _mockSecureStorage = new Mock>(); 30 | _mockLoggingService = new Mock(); 31 | settingsService = new SettingsService(); 32 | 33 | _qrValidatorService = new QrECValidatorService(_mockSecureStorage.Object, 34 | settingsService, _mockLoggingService.Object); 35 | } 36 | 37 | [Test] 38 | public async Task GetECKeyShouldReturnDefaultWithNoJWK() 39 | { 40 | var jwkDto = new JwkDto(); 41 | 42 | _mockSecureStorage.Setup(x => x.GetSecureStorageAsync(It.IsAny())).ReturnsAsync(jwkDto); 43 | 44 | var actual = await _qrValidatorService.GetKeyVaultKey(string.Empty); 45 | IEnumerable expected = default; 46 | 47 | Assert.AreEqual(expected, actual); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 2 9 | 10 | UISupportedInterfaceOrientations 11 | 12 | UIInterfaceOrientationPortrait 13 | 14 | UISupportedInterfaceOrientations~ipad 15 | 16 | UIInterfaceOrientationPortrait 17 | UIInterfaceOrientationPortraitUpsideDown 18 | UIInterfaceOrientationLandscapeLeft 19 | UIInterfaceOrientationLandscapeRight 20 | 21 | MinimumOSVersion 22 | 8.0 23 | CFBundleIdentifier 24 | uk.gov.dhsc.healthrecord 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | CFBundleName 28 | NHSCovidPassVerifier 29 | NSCameraUsageDescription 30 | Please allow access to the camera to scan certificates 31 | UIUserInterfaceStyle 32 | Light 33 | UIViewControllerBasedStatusBarAppearance 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleLightContent 37 | CFBundleShortVersionString 38 | 1.0.0 39 | CFBundleURLTypes 40 | 41 | 42 | CFBundleURLName 43 | NHSCovidPassVerifier url scheme 44 | CFBundleURLSchemes 45 | 46 | uk.gov.dhsc.healthrecord 47 | 48 | CFBundleTypeRole 49 | Viewer 50 | 51 | 52 | CFBundleVersion 53 | 10 54 | CFBundleDisplayName 55 | NHS COVID Pass Verifier 56 | XSAppIconAssets 57 | Assets.xcassets/AppIcon.appiconset 58 | 59 | 60 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/NhsSplashPage.xaml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 33 | 34 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/ScannerResultPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.Utils; 4 | using NHSCovidPassVerifier.ViewModels; 5 | using System.Timers; 6 | using Xamarin.Forms; 7 | using Xamarin.Forms.Xaml; 8 | 9 | namespace NHSCovidPassVerifier.Views 10 | { 11 | [XamlCompilation(XamlCompilationOptions.Compile)] 12 | public partial class ScannerResultPage : ContentPage 13 | { 14 | private readonly Timer _timer; 15 | 16 | private readonly IStatusBarService _statusBarService = IoCContainer.Resolve(); 17 | 18 | private readonly ISettingsService _settingsService = IoCContainer.Resolve(); 19 | 20 | public ScannerResultPage() 21 | { 22 | InitializeComponent(); 23 | BindingContext = IoCContainer.Resolve(); 24 | 25 | this._timer = new Timer(); 26 | _timer.Interval = _settingsService.PressedToReleasedCloseInterval; 27 | } 28 | 29 | private void Button_Pressed(object sender, System.EventArgs e) 30 | { 31 | _timer.Enabled = true; 32 | (BindingContext as ScannerResultViewModel)?.PauseTimer(); 33 | 34 | } 35 | 36 | private void Button_Released(object sender, System.EventArgs e) 37 | { 38 | (BindingContext as ScannerResultViewModel)?.ResumeTimer(); 39 | _timer.Enabled = false; 40 | } 41 | 42 | private void OnTimedEvent(object source, ElapsedEventArgs e) 43 | { 44 | } 45 | 46 | protected override void OnAppearing() 47 | { 48 | _statusBarService.SetDefaultStatusBar(); 49 | base.OnAppearing(); 50 | _timer.Elapsed += OnTimedEvent; 51 | } 52 | 53 | protected override void OnDisappearing() 54 | { 55 | base.OnDisappearing(); 56 | (BindingContext as ScannerResultViewModel)?.PauseTimer(); 57 | _timer.Elapsed -= OnTimedEvent; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Models/Cose/SignatureAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using PeterO.Cbor; 4 | 5 | //MIT License 6 | //Copyright 2021 Myndigheten f�r digital f�rvaltning (DIGG) 7 | namespace NHSCovidPassVerifier.Models.Cose 8 | { 9 | //@author Henrik Bengtsson(extern.henrik.bengtsson @digg.se) 10 | //@author Martin Lindstr�m(martin @idsec.se) 11 | //@author Henric Norlander(extern.henric.norlander @digg.se) 12 | /// 13 | /// Representation of the supported signature algorithms 14 | /// 15 | public class SignatureAlgorithm 16 | { 17 | public static readonly CBORObject ES256 = CBORObject.FromObject(-7); 18 | 19 | public static readonly CBORObject ES384 = CBORObject.FromObject(-35); 20 | 21 | public static readonly CBORObject ES512 = CBORObject.FromObject(-36); 22 | 23 | public static readonly CBORObject PS256 = CBORObject.FromObject(-37); 24 | 25 | public static readonly CBORObject PS384 = CBORObject.FromObject(-38); 26 | 27 | public static readonly CBORObject PS512 = CBORObject.FromObject(-39); 28 | 29 | public static string GetAlgorithmName(CBORObject cborValue) 30 | { 31 | switch (cborValue.AsInt32()) 32 | { 33 | case -7: 34 | return "SHA256withECDSA"; 35 | case -35: 36 | return "SHA384withECDSA"; 37 | case -36: 38 | return "SHA512withECDSA"; 39 | case -37: 40 | return "SHA256withRSA/PSS"; 41 | case -38: 42 | return "SHA384withRSA/PSS"; 43 | case -39: 44 | return "SHA512withRSA/PSS"; 45 | default: 46 | break; 47 | } 48 | return null; 49 | } 50 | 51 | private static CBORObject[] SupportedAlgorithm = { 52 | ES256, 53 | PS256 54 | }; 55 | public static bool IsSupportedAlgorithm(CBORObject cborValue) 56 | { 57 | return SupportedAlgorithm.Contains(cborValue); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /NHSCovidPassVerifier/Views/Elements/ScannerResultElements/InvalidCode.xaml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 49 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/NavigationTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Configuration; 2 | using NHSCovidPassVerifier.Models; 3 | using NHSCovidPassVerifier.Services.Interfaces; 4 | using NHSCovidPassVerifier.Tests.MockServices; 5 | using NHSCovidPassVerifier.ViewModels; 6 | using NHSCovidPassVerifier.Views; 7 | using I18NPortable; 8 | using Moq; 9 | using NUnit.Framework; 10 | 11 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 12 | { 13 | public class NavigationTests 14 | { 15 | private readonly MockNavigationService _mockNavigationService; 16 | 17 | public NavigationTests() 18 | { 19 | _mockNavigationService = new MockNavigationService(); 20 | } 21 | 22 | [Test] 23 | public void PopPageTest() 24 | { 25 | var PopPageResult = _mockNavigationService.PopPage(); 26 | Assert.IsNotNull(PopPageResult); 27 | } 28 | 29 | [Test] 30 | public void PopPageTestTrue() 31 | { 32 | var PopPageResult = _mockNavigationService.PopPage(true); 33 | Assert.IsNotNull(PopPageResult); 34 | } 35 | 36 | [Test] 37 | public void PopPageWithResultTest() 38 | { 39 | var PopPageWithResult = _mockNavigationService.PopPageWithResult(); 40 | Assert.IsNotNull(PopPageWithResult); 41 | } 42 | 43 | [Test] 44 | public void ReplaceTopPageTest() 45 | { 46 | var AboutPageReturn = new AboutPage(); 47 | 48 | var ReplaceTopPageResult = _mockNavigationService.ReplaceTopPage(AboutPageReturn); 49 | Assert.IsNotNull(ReplaceTopPageResult); 50 | } 51 | 52 | [Test] 53 | public void PushModalPageTest() 54 | { 55 | var AboutPageReturn = new AboutPage(); 56 | 57 | var PushModalPageResult = _mockNavigationService.PushModal(AboutPageReturn); 58 | Assert.IsNotNull(PushModalPageResult); 59 | } 60 | 61 | [Test] 62 | public void PushPageTest() 63 | { 64 | var AboutPageReturn = new AboutPage(); 65 | 66 | var PushPageResult = _mockNavigationService.PushPage(AboutPageReturn); 67 | Assert.IsNotNull(PushPageResult); 68 | } 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/ViewModelTests/PrivacyPolicyViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using NHSCovidPassVerifier.Models; 2 | using NHSCovidPassVerifier.Services.Interfaces; 3 | using NHSCovidPassVerifier.ViewModels; 4 | using I18NPortable; 5 | using Moq; 6 | using NUnit.Framework; 7 | 8 | namespace NHSCovidPassVerifier.Tests.ViewModelTests 9 | { 10 | [TestFixture] 11 | public class PrivacyPolicyViewModelTests 12 | { 13 | private readonly PrivacyPolicyViewModel _viewModel; 14 | 15 | public PrivacyPolicyViewModelTests() 16 | { 17 | _viewModel = new PrivacyPolicyViewModel(); 18 | } 19 | 20 | [Test] 21 | public void TextIsCorrect() 22 | { 23 | Assert.AreEqual(_viewModel.PrivacyPolicyTitle, "PRIVACY_TITLE".Translate()); 24 | Assert.AreEqual(_viewModel.PrivacyPolicyText2, "PRIVACY_TEXT_2".Translate()); 25 | 26 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle3, "PRIVACY_SUBTITLE_3".Translate()); 27 | Assert.AreEqual(_viewModel.PrivacyPolicyText3, "PRIVACY_TEXT_3".Translate()); 28 | 29 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle4, "PRIVACY_SUBTITLE_4".Translate()); 30 | Assert.AreEqual(_viewModel.PrivacyPolicyText4, "PRIVACY_TEXT_4".Translate()); 31 | 32 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle5, "PRIVACY_SUBTITLE_5".Translate()); 33 | Assert.AreEqual(_viewModel.PrivacyPolicyText5, "PRIVACY_TEXT_5".Translate()); 34 | 35 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle6, "PRIVACY_SUBTITLE_6".Translate()); 36 | Assert.AreEqual(_viewModel.PrivacyPolicyText6, "PRIVACY_TEXT_6".Translate()); 37 | 38 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle7, "PRIVACY_SUBTITLE_7".Translate()); 39 | Assert.AreEqual(_viewModel.PrivacyPolicyText7, "PRIVACY_TEXT_7".Translate()); 40 | 41 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle7_1, "PRIVACY_SUBTITLE_7_1".Translate()); 42 | Assert.AreEqual(_viewModel.PrivacyPolicyText7_1, "PRIVACY_TEXT_7_1".Translate()); 43 | 44 | Assert.AreEqual(_viewModel.PrivacyPolicySubtitle9, "PRIVACY_SUBTITLE_9".Translate()); 45 | Assert.AreEqual(_viewModel.PrivacyPolicyText9, "PRIVACY_TEXT_9".Translate()); 46 | 47 | } 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /NHSCovidPassVerifier.Tests/UtilsTests/DateUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NHSCovidPassVerifier.Utils; 3 | using I18NPortable; 4 | using NUnit.Framework; 5 | 6 | namespace NHSCovidPassVerifier.Tests.UtilsTests 7 | { 8 | public class DateUtilsTests 9 | { 10 | 11 | [TestCase("01/08/2021 14:00:00", "8 Jan 2021 at 14:00")] 12 | [TestCase("05/29/2021", "29 May 2021 at 00:00")] 13 | [TestCase("1/9/2021 05:50:06", "9 Jan 2021 at 05:50")] 14 | [TestCase("2021/10/12", "12 Oct 2021 at 00:00")] 15 | [TestCase("2021-02-28T05:50:06", "28 Feb 2021 at 05:50")] 16 | public void TestFormatDateTime(DateTime date, string expected) 17 | { 18 | var actual = date.FormatDateTime(); 19 | 20 | Assert.AreEqual(expected, actual); 21 | } 22 | 23 | [Test] 24 | public void TestFormatTimeToMidnight() 25 | { 26 | //Given 27 | var midnight = DateTime.Parse("2021/10/12 00:00:00"); 28 | //When 29 | var actual = DateUtils.FormatTimeToMidnightMidday(midnight); 30 | //Then 31 | Assert.AreEqual("MIDNIGHT_TEXT".Translate(), actual); 32 | } 33 | 34 | [Test] 35 | public void TestFormatTimeToMidday() 36 | { 37 | //Given 38 | var midnight = DateTime.Parse("2021/10/12 12:00:00"); 39 | //When 40 | var actual = DateUtils.FormatTimeToMidnightMidday(midnight); 41 | //Then 42 | Assert.AreEqual("MIDDAY_TEXT".Translate(), actual); 43 | } 44 | 45 | [TestCase("01/08/2021 11:00:00")] 46 | [TestCase("1/9/2021 05:50:06")] 47 | [TestCase("2021-02-28T05:50:06")] 48 | public void TestFormatTimeToMidnightMiddayAm(DateTime date) 49 | { 50 | var actual = DateUtils.FormatTimeToMidnightMidday(date); 51 | Assert.That(actual, Does.EndWith("am")); 52 | } 53 | 54 | [TestCase("01/08/2021 14:00:00")] 55 | [TestCase("1/9/2021 21:50:06")] 56 | [TestCase("2021-02-28T15:50:06")] 57 | public void TestFormatTimeToMidnightMiddayPm(DateTime date) 58 | { 59 | var actual = DateUtils.FormatTimeToMidnightMidday(date); 60 | Assert.That(actual, Does.EndWith("pm")); 61 | } 62 | } 63 | } --------------------------------------------------------------------------------