diff --git a/administration/src/cards/PdfFactory.ts b/administration/src/cards/PdfFactory.ts index 26603c311..53105d14e 100644 --- a/administration/src/cards/PdfFactory.ts +++ b/administration/src/cards/PdfFactory.ts @@ -132,7 +132,7 @@ function fillCodeArea(qrCode: PdfQrCode, x: number, y: number, size: number, pag export async function generatePdf( dynamicCodes: DynamicActivationCode[], - staticCodes: StaticVerificationCode[] | null, + staticCodes: StaticVerificationCode[], region: Region, pdfConfig: PdfConfig ) { @@ -143,7 +143,7 @@ export async function generatePdf( ? await PDFDocument.load(await fetch(pdfConfig.templatePath).then(res => res.arrayBuffer())) : null - if (staticCodes !== null && dynamicCodes.length !== staticCodes.length) { + if (staticCodes.length !== 0 && dynamicCodes.length !== staticCodes.length) { throw new Error('Activation codes count does not match static codes count.') } diff --git a/administration/src/cards/activation.ts b/administration/src/cards/activation.ts deleted file mode 100644 index fa4920aba..000000000 --- a/administration/src/cards/activation.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { DynamicActivationCode, StaticVerificationCode } from '../generated/card_pb' -import { - AddCardDocument, - AddCardMutation, - AddCardMutationVariables, - CardGenerationModelInput, - CodeType, - Region, -} from '../generated/graphql' -import hashCardInfo from './hashCardInfo' -import { ApolloClient } from '@apollo/client' -import { uint8ArrayToBase64 } from '../util/base64' - -export async function createCard( - client: ApolloClient, - activationCode: T, - region: Region, - codeType: T extends DynamicActivationCode ? CodeType.Dynamic : CodeType.Static -) { - const cardInfoHash = await hashCardInfo(activationCode.info!, activationCode.pepper) - const expirationDay = activationCode.info!.expirationDay - const activationSecretBase64 = - activationCode instanceof DynamicActivationCode ? uint8ArrayToBase64(activationCode.activationSecret) : null - const card: CardGenerationModelInput = { - cardExpirationDay: expirationDay ?? null, // JS number can represent integers up to 2^53, so it can represent all values of an uint32 (protobuf) - cardInfoHashBase64: uint8ArrayToBase64(cardInfoHash), - activationSecretBase64: activationSecretBase64, - regionId: region.id, - codeType, - } - - return await client.mutate({ - mutation: AddCardDocument, - variables: { card }, - }) -} - -export async function createCards( - client: ApolloClient, - activationCodes: T[], - region: Region, - codeType: T extends DynamicActivationCode ? CodeType.Dynamic : CodeType.Static -) { - const results = await Promise.all( - activationCodes.map(async activationCode => createCard(client, activationCode, region, codeType)) - ) - - const firstFailure = results.find(result => !result.data?.success) - if (firstFailure) { - throw Error(JSON.stringify(firstFailure)) - } -} diff --git a/administration/src/cards/creation.ts b/administration/src/cards/creation.ts new file mode 100644 index 000000000..87e24da1f --- /dev/null +++ b/administration/src/cards/creation.ts @@ -0,0 +1,40 @@ +import { DynamicActivationCode, StaticVerificationCode } from '../generated/card_pb' +import { + AddCardsDocument, + AddCardsMutation, + AddCardsMutationVariables, + CardGenerationModelInput, + CodeType, + Region, +} from '../generated/graphql' +import hashCardInfo from './hashCardInfo' +import { ApolloClient } from '@apollo/client' +import { uint8ArrayToBase64 } from '../util/base64' + +type Codes = (DynamicActivationCode | StaticVerificationCode)[] + +export async function createCards(client: ApolloClient, activationCodes: Codes, region: Region) { + const cards: CardGenerationModelInput[] = await Promise.all( + activationCodes.map(async code => { + const codeType = code instanceof DynamicActivationCode ? CodeType.Dynamic : CodeType.Static + const cardInfoHash = await hashCardInfo(code.info!, code.pepper) + const expirationDay = code.info!.expirationDay + const activationSecretBase64 = + code instanceof DynamicActivationCode ? uint8ArrayToBase64(code.activationSecret) : null + return { + cardExpirationDay: expirationDay ?? null, // JS number can represent integers up to 2^53, so it can represent all values of an uint32 (protobuf) + cardInfoHashBase64: uint8ArrayToBase64(cardInfoHash), + activationSecretBase64: activationSecretBase64, + regionId: region.id, + codeType, + } + }) + ) + const result = await client.mutate({ + mutation: AddCardsDocument, + variables: { cards }, + }) + if (!result.data?.success) { + throw Error(JSON.stringify(result)) + } +} diff --git a/administration/src/components/cards/CreateCardsController.tsx b/administration/src/components/cards/CreateCardsController.tsx index 4f34adb2c..a229a2b5b 100644 --- a/administration/src/components/cards/CreateCardsController.tsx +++ b/administration/src/components/cards/CreateCardsController.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useState } from 'react' +import { useContext, useState } from 'react' import { Spinner } from '@blueprintjs/core' import { CardBlueprint } from '../../cards/CardBlueprint' import CreateCardsForm from './CreateCardsForm' @@ -7,10 +7,10 @@ import { useAppToaster } from '../AppToaster' import GenerationFinished from './CardsCreatedMessage' import downloadDataUri from '../../util/downloadDataUri' import { WhoAmIContext } from '../../WhoAmIProvider' -import { createCards } from '../../cards/activation' +import { createCards } from '../../cards/creation' import { ProjectConfigContext } from '../../project-configs/ProjectConfigContext' -import { CodeType, Region } from '../../generated/graphql' import { generatePdf } from '../../cards/PdfFactory' +import { Region } from '../../generated/graphql' enum CardActivationState { input, @@ -51,13 +51,12 @@ const InnerCreateCardsController = ({ region }: { region: Region }) => { ? cardBlueprints.map(cardBlueprints => { return cardBlueprints.generateStaticVerificationCode() }) - : null + : [] const pdfDataUri = await generatePdf(dynamicCodes, staticCodes, region, projectConfig.pdf) - await createCards(client, dynamicCodes, region, CodeType.Dynamic) - - if (staticCodes) await createCards(client, staticCodes, region, CodeType.Static) + const codes = [...dynamicCodes, ...staticCodes] + await createCards(client, codes, region) downloadDataUri(pdfDataUri, 'berechtigungskarten.pdf') setState(CardActivationState.finished) diff --git a/administration/src/graphql/verification/addCard.graphql b/administration/src/graphql/verification/addCard.graphql index 088d77625..5e3bff380 100644 --- a/administration/src/graphql/verification/addCard.graphql +++ b/administration/src/graphql/verification/addCard.graphql @@ -1,3 +1,3 @@ -mutation addCard($card: CardGenerationModelInput!) { - success: addCard(card: $card) +mutation addCards($cards: [CardGenerationModelInput!]!) { + success: addCards(cards: $cards) } diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/verification/webservice/schema/CardMutationService.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/verification/webservice/schema/CardMutationService.kt index 3843fd290..ebf66a296 100644 --- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/verification/webservice/schema/CardMutationService.kt +++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/verification/webservice/schema/CardMutationService.kt @@ -19,34 +19,38 @@ import java.util.Base64 @Suppress("unused") class CardMutationService { - @GraphQLDescription("Stores a new digital entitlement card") - fun addCard(dfe: DataFetchingEnvironment, card: CardGenerationModel): Boolean { + @GraphQLDescription("Stores a batch of new digital entitlementcards") + fun addCards(dfe: DataFetchingEnvironment, cards: List): Boolean { val jwtPayload = dfe.getContext().enforceSignedIn() - if (!validateNewCard(card)) throw Exception("Card invalid.") - transaction { val user = AdministratorEntity.findById(jwtPayload.adminId) ?: throw UnauthorizedException() - val targetedRegionId = card.regionId - if (!Authorizer.mayCreateCardInRegion(user, targetedRegionId)) { - throw UnauthorizedException() - } - val activationSecret = - card.activationSecretBase64?.let { - val decodedRawActivationSecret = Base64.getDecoder().decode(it) - CardActivator.hashActivationSecret(decodedRawActivationSecret) + + for (card in cards) { + val targetedRegionId = card.regionId + if (!Authorizer.mayCreateCardInRegion(user, targetedRegionId)) { + throw UnauthorizedException() } + if (!validateNewCard(card)) { + throw Exception("Invalid cart.") + } + val activationSecret = + card.activationSecretBase64?.let { + val decodedRawActivationSecret = Base64.getDecoder().decode(it) + CardActivator.hashActivationSecret(decodedRawActivationSecret) + } - CardRepository.insert( - Base64.getDecoder().decode(card.cardInfoHashBase64), - activationSecret, - card.cardExpirationDay, - card.regionId, - user.id.value, - card.codeType, - ) + CardRepository.insert( + Base64.getDecoder().decode(card.cardInfoHashBase64), + activationSecret, + card.cardExpirationDay, + card.regionId, + user.id.value, + card.codeType + ) + } } return true } diff --git a/frontend/android/app/build.gradle b/frontend/android/app/build.gradle index 3bf0e8dda..304dcbc75 100644 --- a/frontend/android/app/build.gradle +++ b/frontend/android/app/build.gradle @@ -101,6 +101,11 @@ android { buildTypes { release { + ndk { + // Flutter does not support x86, so we exclude it in the following list: https://github.com/flutter/flutter/issues/9253 + abiFilters 'armeabi-v7a','arm64-v8a','x86_64' + } + if (localProperties.containsKey("signing.keyAlias")) { signingConfig signingConfigs.localProps } else { diff --git a/frontend/ios/Gemfile.lock b/frontend/ios/Gemfile.lock index 938c713e8..3eb9cd2e2 100644 --- a/frontend/ios/Gemfile.lock +++ b/frontend/ios/Gemfile.lock @@ -9,35 +9,35 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.547.0) - aws-sdk-core (3.125.2) + aws-partitions (1.698.0) + aws-sdk-core (3.169.0) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.525.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.62.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-kms (1.53.0) - aws-sdk-core (~> 3, >= 3.125.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.111.1) - aws-sdk-core (~> 3, >= 3.125.0) + aws-sdk-s3 (1.118.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.4.0) + aws-sigv4 (1.5.2) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) - claide (1.0.3) - cocoapods (1.11.2) + claide (1.1.0) + cocoapods (1.11.3) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.11.2) + cocoapods-core (= 1.11.3) cocoapods-deintegrate (>= 1.0.3, < 2.0) cocoapods-downloader (>= 1.4.0, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) @@ -52,7 +52,7 @@ GEM nap (~> 1.0) ruby-macho (>= 1.0, < 3.0) xcodeproj (>= 1.21.0, < 2.0) - cocoapods-core (1.11.2) + cocoapods-core (1.11.3) activesupport (>= 5.0, < 7) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -63,7 +63,7 @@ GEM public_suffix (~> 4.0) typhoeus (~> 1.0) cocoapods-deintegrate (1.0.5) - cocoapods-downloader (1.5.1) + cocoapods-downloader (1.6.3) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.1) @@ -75,19 +75,19 @@ GEM colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - concurrent-ruby (1.1.10) + concurrent-ruby (1.2.0) declarative (0.0.20) digest-crc (0.6.4) rake (>= 12.0.0, < 14.0.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) + dotenv (2.8.1) emoji_regex (3.2.3) escape (0.0.4) - ethon (0.15.0) + ethon (0.16.0) ffi (>= 1.15.0) - excon (0.89.0) - faraday (1.9.3) + excon (0.97.2) + faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -106,8 +106,8 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) @@ -116,7 +116,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.199.0) + fastlane (2.211.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -159,9 +159,9 @@ GEM fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.15.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-core (0.4.1) + google-apis-androidpublisher_v3 (0.32.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-core (0.9.5) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -170,44 +170,44 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.10.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-playcustomapp_v1 (0.7.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-storage_v1 (0.11.0) - google-apis-core (>= 0.4, < 2.a) + google-apis-iamcredentials_v1 (0.16.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-playcustomapp_v1 (0.12.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.5.0) - faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.2.0) - google-cloud-storage (1.36.0) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + google-cloud-errors (1.3.0) + google-cloud-storage (1.44.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.1.0) - faraday (>= 0.17.3, < 2.0) + googleauth (1.3.0) + faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.4) + http-cookie (1.0.5) domain_name (~> 0.5) httpclient (2.8.3) i18n (1.12.0) concurrent-ruby (~> 1.0) - jmespath (1.6.1) - json (2.6.1) - jwt (2.3.0) + jmespath (1.6.2) + json (2.6.3) + jwt (2.6.0) memoist (0.16.2) - mini_magick (4.11.0) + mini_magick (4.12.0) mini_mime (1.1.2) minitest (5.17.0) molinillo (0.8.0) @@ -220,9 +220,9 @@ GEM optparse (0.1.1) os (1.1.4) plist (3.6.0) - public_suffix (4.0.6) + public_suffix (4.0.7) rake (13.0.6) - representable (3.1.1) + representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) @@ -233,9 +233,9 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.16.0) + signet (0.17.0) addressable (~> 2.8) - faraday (>= 0.17.3, < 2.0) + faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) simctl (1.6.8) @@ -256,11 +256,11 @@ GEM uber (0.1.0) unf (0.1.4) unf_ext - unf_ext (0.0.8) + unf_ext (0.0.8.2) unicode-display_width (1.8.0) webrick (1.7.0) word_wrap (1.0.0) - xcodeproj (1.21.0) + xcodeproj (1.22.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) @@ -281,4 +281,4 @@ DEPENDENCIES fastlane BUNDLED WITH - 2.1.4 + 1.17.2 diff --git a/frontend/ios/Runner.xcodeproj/project.pbxproj b/frontend/ios/Runner.xcodeproj/project.pbxproj index fd8e6dc85..8bc81cf7e 100644 --- a/frontend/ios/Runner.xcodeproj/project.pbxproj +++ b/frontend/ios/Runner.xcodeproj/project.pbxproj @@ -26,20 +26,6 @@ remoteGlobalIDString = C1C1AD8C20613ACC67F00155D7BB54AA; remoteInfo = flutter_secure_storage; }; - 0B1FA81326DBD06400D4AEA7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = ED1DEDDDDA9BFD4363F16BC20228BFCF; - remoteInfo = maps_launcher; - }; - 0B1FA81526DBD06400D4AEA7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2AD35495F0539645B05298768B095719; - remoteInfo = MTBBarcodeScanner; - }; 0B1FA81B26DBD06400D4AEA7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; @@ -47,13 +33,6 @@ remoteGlobalIDString = 669E8F25E1897672BDB80B7EB784DA24; remoteInfo = "Pods-Runner"; }; - 0B1FA81D26DBD06400D4AEA7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8EDC0AE1F9076AD2F7A1FDCD374A002C; - remoteInfo = qr_code_scanner; - }; 0B330E3927143BA80011A908 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; @@ -82,6 +61,69 @@ remoteGlobalIDString = 502E20F09A7CAFBD1DE1AA882DCC550C; remoteInfo = geolocator_apple; }; + 502F2F2429803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 856B5CD56F194FAD26EA91620B66D614; + remoteInfo = GoogleDataTransport; + }; + 502F2F2629803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 251C6319AD50CB50F18D50CBF727F8B2; + remoteInfo = GoogleToolboxForMac; + }; + 502F2F2829803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = B43874C6CBB50E7134FBEC24BABFE14F; + remoteInfo = GoogleUtilities; + }; + 502F2F2A29803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 28A6DB952CEA79E3902D41748273A364; + remoteInfo = GoogleUtilitiesComponents; + }; + 502F2F2C29803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = C1998E0D8085221AD87F89B614C10E52; + remoteInfo = GTMSessionFetcher; + }; + 502F2F2E29803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0F7C1C60107CFDFC0652DEA0F788BEEB; + remoteInfo = mobile_scanner; + }; + 502F2F3029803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 06FC5C9CF96D60C50FCD47D339C91951; + remoteInfo = nanopb; + }; + 502F2F3229803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3347A1AB6546F0A3977529B8F199DC41; + remoteInfo = PromisesObjC; + }; + 502F2F3429803DDE00B6F8ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = C2105C94812B6214B154F54DCEDB72AC; + remoteInfo = Protobuf; + }; 5093F3E128D8D252009A9A33 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0B1FA7F026DBD06400D4AEA7 /* Pods.xcodeproj */; @@ -205,15 +247,21 @@ 0BE935D1274FD4CA004AF690 /* connectivity_plus */, 0B1FA80826DBD06400D4AEA7 /* flutter_secure_storage */, 0BE935D3274FD4CA004AF690 /* geolocator_apple */, + 502F2F2529803DDE00B6F8ED /* GoogleDataTransport */, + 502F2F2729803DDE00B6F8ED /* GoogleToolboxForMac */, + 502F2F2929803DDE00B6F8ED /* GoogleUtilities */, + 502F2F2B29803DDE00B6F8ED /* GoogleUtilitiesComponents */, + 502F2F2D29803DDE00B6F8ED /* GTMSessionFetcher */, 0B330E3A27143BA80011A908 /* maplibre_gl */, 5093F3E228D8D252009A9A33 /* MapLibreAnnotationExtension-framework */, 5093F3E428D8D252009A9A33 /* MapLibreAnnotationExtension-library */, - 0B1FA81426DBD06400D4AEA7 /* maps_launcher */, - 0B1FA81626DBD06400D4AEA7 /* MTBBarcodeScanner */, + 502F2F2F29803DDE00B6F8ED /* mobile_scanner */, + 502F2F3129803DDE00B6F8ED /* nanopb */, 5093F3E628D8D252009A9A33 /* package_info_plus */, 5093F3E828D8D252009A9A33 /* path_provider_ios */, 0B1FA81C26DBD06400D4AEA7 /* Pods-Runner */, - 0B1FA81E26DBD06400D4AEA7 /* qr_code_scanner */, + 502F2F3329803DDE00B6F8ED /* PromisesObjC */, + 502F2F3529803DDE00B6F8ED /* Protobuf */, 5093F3EA28D8D252009A9A33 /* ReachabilitySwift */, 5093F3EC28D8D252009A9A33 /* shared_preferences_ios */, 5093F3EE28D8D252009A9A33 /* url_launcher_ios */, @@ -402,22 +450,6 @@ remoteRef = 0B1FA80726DBD06400D4AEA7 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 0B1FA81426DBD06400D4AEA7 /* maps_launcher */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - name = maps_launcher; - path = maps_launcher.framework; - remoteRef = 0B1FA81326DBD06400D4AEA7 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 0B1FA81626DBD06400D4AEA7 /* MTBBarcodeScanner */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - name = MTBBarcodeScanner; - path = MTBBarcodeScanner.framework; - remoteRef = 0B1FA81526DBD06400D4AEA7 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 0B1FA81C26DBD06400D4AEA7 /* Pods-Runner */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -426,14 +458,6 @@ remoteRef = 0B1FA81B26DBD06400D4AEA7 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 0B1FA81E26DBD06400D4AEA7 /* qr_code_scanner */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - name = qr_code_scanner; - path = qr_code_scanner.framework; - remoteRef = 0B1FA81D26DBD06400D4AEA7 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 0B330E3A27143BA80011A908 /* maplibre_gl */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -458,6 +482,78 @@ remoteRef = 0BE935D2274FD4CA004AF690 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 502F2F2529803DDE00B6F8ED /* GoogleDataTransport */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = GoogleDataTransport; + path = GoogleDataTransport.framework; + remoteRef = 502F2F2429803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F2729803DDE00B6F8ED /* GoogleToolboxForMac */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = GoogleToolboxForMac; + path = GoogleToolboxForMac.framework; + remoteRef = 502F2F2629803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F2929803DDE00B6F8ED /* GoogleUtilities */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = GoogleUtilities; + path = GoogleUtilities.framework; + remoteRef = 502F2F2829803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F2B29803DDE00B6F8ED /* GoogleUtilitiesComponents */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = GoogleUtilitiesComponents; + path = GoogleUtilitiesComponents.framework; + remoteRef = 502F2F2A29803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F2D29803DDE00B6F8ED /* GTMSessionFetcher */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = GTMSessionFetcher; + path = GTMSessionFetcher.framework; + remoteRef = 502F2F2C29803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F2F29803DDE00B6F8ED /* mobile_scanner */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = mobile_scanner; + path = mobile_scanner.framework; + remoteRef = 502F2F2E29803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F3129803DDE00B6F8ED /* nanopb */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = nanopb; + path = nanopb.framework; + remoteRef = 502F2F3029803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F3329803DDE00B6F8ED /* PromisesObjC */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = PromisesObjC; + path = FBLPromises.framework; + remoteRef = 502F2F3229803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 502F2F3529803DDE00B6F8ED /* Protobuf */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + name = Protobuf; + path = Protobuf.framework; + remoteRef = 502F2F3429803DDE00B6F8ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 5093F3E228D8D252009A9A33 /* MapLibreAnnotationExtension-framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -581,7 +677,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; }; E34397E4514BA1A3CBC8283B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -671,7 +767,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -702,7 +798,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -730,7 +826,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -804,10 +900,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_bayern; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -823,8 +921,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -894,10 +994,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_nuernberg; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -913,8 +1015,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -935,7 +1039,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1013,10 +1117,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_nuernberg; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1032,8 +1138,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1053,7 +1161,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1127,10 +1235,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_nuernberg; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1146,8 +1256,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1167,7 +1279,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1245,10 +1357,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_bayern; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1264,8 +1378,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1286,7 +1402,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1364,10 +1480,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_bayern; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1383,8 +1501,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1404,7 +1524,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1478,10 +1598,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_bayern; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1497,8 +1619,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1518,7 +1642,7 @@ DEVELOPMENT_TEAM = P9FYW37G78; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = ScreenshotTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1650,10 +1774,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_bayern; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1669,8 +1795,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1684,10 +1812,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = app_icon_bayern; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7272KE28TJ; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 7272KE28TJ; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1703,8 +1833,10 @@ "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = "$(BUILD_CONFIG_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = app.sozialpass.nuernberg; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match Development de.nrw.it.ehrensachebayern"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore app.sozialpass.nuernberg"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/frontend/ios/Runner.xcodeproj/xcshareddata/xcschemes/Bayern.xcscheme b/frontend/ios/Runner.xcodeproj/xcshareddata/xcschemes/Bayern.xcscheme index 762a9ad65..f1e1b3c76 100644 --- a/frontend/ios/Runner.xcodeproj/xcshareddata/xcschemes/Bayern.xcscheme +++ b/frontend/ios/Runner.xcodeproj/xcshareddata/xcschemes/Bayern.xcscheme @@ -47,6 +47,16 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + Bool { - clearITNRWStorage() - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + clearITNRWStorage() + + if ProcessInfo.processInfo.arguments.contains("UI-Testing") { + UserDefaults.standard.set(false, forKey: "flutter.firstStart"); + } + + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } func clearITNRWStorage() { let preferences = UserDefaults.standard @@ -19,12 +24,12 @@ import Flutter if preferences.string(forKey: key) != nil { //clear preferences resetDefaults() - + //clear storage removeCache() } } - + func resetDefaults() { let defs = UserDefaults.standard let dict = defs.dictionaryRepresentation() diff --git a/frontend/ios/Runner/Info.plist b/frontend/ios/Runner/Info.plist index 004cb6bd3..a4f30c541 100644 --- a/frontend/ios/Runner/Info.plist +++ b/frontend/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -55,9 +57,5 @@ io.flutter.embedded_views_preview - ITSAppUsesNonExemptEncryption - - CADisableMinimumFrameDurationOnPhone - diff --git a/frontend/ios/ScreenshotTests/ScreenshotTests.swift b/frontend/ios/ScreenshotTests/ScreenshotTests.swift index 22c8c8242..3e594c5d9 100644 --- a/frontend/ios/ScreenshotTests/ScreenshotTests.swift +++ b/frontend/ios/ScreenshotTests/ScreenshotTests.swift @@ -34,11 +34,12 @@ class ScreenshotTests: XCTestCase { func testOpenMap() throws { let app = XCUIApplication() setupSnapshot(app) + app.launchArguments += ["UI-Testing"] app.launch() - let element = app.staticTexts["Suche\nTab 2 von 3"] + let element = app.staticTexts["Suche\nTab 2 von 4"] self.waitForElementToAppear(element: element) - sleep(5) + sleep(10) snapshot("01Map") } @@ -46,13 +47,14 @@ class ScreenshotTests: XCTestCase { func testOpenSearch() throws { let app = XCUIApplication() setupSnapshot(app) + app.launchArguments += ["UI-Testing"] app.launch() - let element = app.staticTexts["Suche\nTab 2 von 3"] + let element = app.staticTexts["Suche\nTab 2 von 4"] self.waitForElementToAppear(element: element) sleep(5) - XCUIApplication().staticTexts["Suche\nTab 2 von 3"].tap() + XCUIApplication().staticTexts["Suche\nTab 2 von 4"].tap() snapshot("01Search") } @@ -60,26 +62,27 @@ class ScreenshotTests: XCTestCase { func testOpenDetail() throws { let app = XCUIApplication() setupSnapshot(app) + app.launchArguments += ["UI-Testing"] app.launch() - let element = app.staticTexts["Suche\nTab 2 von 3"] + let element = app.staticTexts["Suche\nTab 2 von 4"] self.waitForElementToAppear(element: element) sleep(5) - app.staticTexts["Suche\nTab 2 von 3"].tap() + app.staticTexts["Suche\nTab 2 von 4"].tap() let search = app.textFields["Tippen, um zu suchen …"] search.tap() search.tap() - search.typeText("Alpha-Caf") + search.typeText("Eiscafe") search.typeText("\n") // Close keyboard for more space app.images.matching(identifier: "Essen/Trinken/Gastronomie").element(boundBy: 0).tap() // on ipads the list element is a "otherElements" element, on iphones it is a "staticTexts" - var result = app.descendants(matching: .any).element(matching: NSPredicate(format: "label CONTAINS[c] %@", "Alpha")) - + var result = app.descendants(matching: .any).element(matching: NSPredicate(format: "label CONTAINS[c] %@", "Dolomiti")) + //if (!result.exists || !result.isHittable) { // result = app.otherElements.element(matching: NSPredicate(format: "label CONTAINS[c] %@", "Alpha")) //} diff --git a/frontend/ios/fastlane/Appfile b/frontend/ios/fastlane/Appfile index 1a14fbde9..7de1a4238 100644 --- a/frontend/ios/fastlane/Appfile +++ b/frontend/ios/fastlane/Appfile @@ -1,4 +1,5 @@ -app_identifier("de.nrw.it.ehrensachebayern") # The bundle identifier of your app +# app_identifier("de.nrw.it.ehrensachebayern") # The bundle identifier of your app +# app_identifier("app.sozialpass.nuernberg") # The bundle identifier of your app # apple_id("[[APPLE_ID]]") # Your Apple email address diff --git a/frontend/ios/fastlane/Matchfile b/frontend/ios/fastlane/Matchfile index d44ad521a..0a40ac5ec 100644 --- a/frontend/ios/fastlane/Matchfile +++ b/frontend/ios/fastlane/Matchfile @@ -1,4 +1,4 @@ -git_url("git@github.com:Integreat/app-credentials.git") +git_url("git@github.com:digitalfabrik/app-credentials.git") git_branch("main") storage_mode("git") diff --git a/frontend/ios/fastlane/Snapfile b/frontend/ios/fastlane/Snapfile index a13b62948..b7da7dfc4 100644 --- a/frontend/ios/fastlane/Snapfile +++ b/frontend/ios/fastlane/Snapfile @@ -1,12 +1,10 @@ devices([ - "iPhone 8", - "iPhone 8 Plus", - "iPhone 11", - "iPhone 11 Pro", - "iPhone 11 Pro Max", - "iPhone SE (2nd generation)", - "iPad Pro (12.9-inch) (5th generation)", - "iPad Pro (11-inch) (3rd generation)", +# https://stackoverflow.com/a/52311326 +"iPhone 8 Plus", # 5.5" +"iPhone 11 Pro Max", # 6.5" +"iPhone 14 Pro Max", # 6.7" +"iPad Pro (12.9-inch) (6th generation)", +"iPad Pro (12.9-inch) (2nd generation)" ]) languages([ diff --git a/frontend/ios/fastlane/SnapshotHelper.swift b/frontend/ios/fastlane/SnapshotHelper.swift index 015cfeaa5..da063ba1c 100644 --- a/frontend/ios/fastlane/SnapshotHelper.swift +++ b/frontend/ios/fastlane/SnapshotHelper.swift @@ -165,7 +165,7 @@ open class Snapshot: NSObject { } let screenshot = XCUIScreen.main.screenshot() - #if os(iOS) + #if os(iOS) && !targetEnvironment(macCatalyst) let image = XCUIDevice.shared.orientation.isLandscape ? fixLandscapeOrientation(image: screenshot.image) : screenshot.image #else let image = screenshot.image @@ -181,7 +181,7 @@ open class Snapshot: NSObject { let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png") #if swift(<5.0) - UIImagePNGRepresentation(image)?.write(to: path, options: .atomic) + try UIImagePNGRepresentation(image)?.write(to: path, options: .atomic) #else try image.pngData()?.write(to: path, options: .atomic) #endif @@ -306,4 +306,4 @@ private extension CGFloat { // Please don't remove the lines below // They are used to detect outdated configuration files -// SnapshotHelperVersion [1.27] +// SnapshotHelperVersion [1.29] diff --git a/frontend/lib/configuration/definitions.dart b/frontend/lib/configuration/definitions.dart index 2ad0c9896..a866c5c83 100644 --- a/frontend/lib/configuration/definitions.dart +++ b/frontend/lib/configuration/definitions.dart @@ -1,13 +1,16 @@ -const String appEnvironment = String.fromEnvironment("environment", defaultValue: "staging"); +const String showcase = "showcase"; +const String production = "production"; +const String local = "local"; +const String appEnvironment = String.fromEnvironment("environment", defaultValue: showcase); bool isProduction() { - return appEnvironment == "production"; + return appEnvironment == production; } bool isLocal() { - return appEnvironment == "local"; + return appEnvironment == local; } bool isShowcase() { - return appEnvironment == "showcase"; + return appEnvironment == showcase; } diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index bf9dbb553..777c5dd64 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -666,13 +666,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" - mutex: - dependency: "direct main" - description: - name: mutex - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" nested: dependency: transitive description: diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index 11715261e..ae383194f 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -41,7 +41,6 @@ dependencies: flutter_secure_storage: ^6.0.0 infinite_scroll_pagination: ^3.2.0 geolocator: ^9.0.1 - mutex: ^3.0.0 protobuf: ^2.1.0 base32: ^2.1.3 qr_flutter: ^4.0.0 diff --git a/specs/backend-api.graphql b/specs/backend-api.graphql index 52a921f71..27e0e7575 100644 --- a/specs/backend-api.graphql +++ b/specs/backend-api.graphql @@ -86,8 +86,8 @@ type Coordinates { type Mutation { "Activate a dynamic entitlement card" activateCard(activationSecretBase64: String!, cardInfoHashBase64: String!, overwrite: Boolean!, project: String!): CardActivationResultModel! - "Stores a new digital entitlement card" - addCard(card: CardGenerationModelInput!): Boolean! + "Stores a batch of new digital entitlementcards" + addCards(cards: [CardGenerationModelInput!]!): Boolean! "Stores a new application for an EAK" addEakApplication(application: ApplicationInput!, regionId: Int!): Boolean! "Changes an administrator's password"