Skip to content

Commit

Permalink
refactor: rewrite certificate check module to be more detailed
Browse files Browse the repository at this point in the history
  • Loading branch information
castdrian committed Aug 16, 2024
1 parent 8f0b90d commit ad83de9
Show file tree
Hide file tree
Showing 16 changed files with 127 additions and 111 deletions.
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ coverage
dist/
expo-env.d.ts
apps/expo/.gitignore
ios/
android/
!modules/*/ios/
!modules/*/android/

# Ignore top-level ios and android directories
apps/expo/ios/
apps/expo/android/

# production
build
Expand Down
6 changes: 6 additions & 0 deletions apps/expo/modules/check-ios-app-id/expo-module.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"platforms": ["ios"],
"ios": {
"modules": ["CheckIosAppIdModule"]
}
}
9 changes: 9 additions & 0 deletions apps/expo/modules/check-ios-app-id/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import CheckIosAppIdModule from "./src/CheckIosAppIdModule";

export function isIncorrectAppId(): boolean {
return CheckIosAppIdModule.isIncorrectAppId();
}

export function getAppId(): string {
return CheckIosAppIdModule.getAppId();
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Pod::Spec.new do |s|
s.name = 'CheckIosCertificate'
s.name = 'CheckIosAppId'
s.version = '1.0.0'
s.summary = 'Check if iOS certificate is Development or Production.'
s.description = 'Check if iOS certificate is Development or Production.'
s.summary = 'Check if iOS App ID is explicit or wildcard.'
s.description = 'Check if iOS App ID is explicit or wildcard.'
s.author = 'castdrian'
s.homepage = 'https://docs.expo.dev/modules/'
s.platforms = { :ios => '13.4', :tvos => '13.4' }
Expand Down
54 changes: 54 additions & 0 deletions apps/expo/modules/check-ios-app-id/ios/CheckIosAppIdModule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import ExpoModulesCore

public class CheckIosAppIdModule: Module {
public func definition() -> ModuleDefinition {
Name("CheckIosAppId")

Function("isIncorrectAppId") { () -> Bool in
#if targetEnvironment(simulator)
return false
#else
guard let appId = self.extractAppId() else {
return false
}

return appId.hasSuffix(".*") || (Bundle.main.bundleIdentifier != nil && !appId.contains(Bundle.main.bundleIdentifier!))
#endif
}

// Function to get the App ID from the provisioning profile
Function("getAppId") { () -> String? in
#if targetEnvironment(simulator)
return nil
#else
return self.extractAppId()
#endif
}
}

// Helper function to extract the application-identifier value from the provisioning profile
private func extractAppId() -> String? {
guard let filePath = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision") else {
return nil
}

let fileURL = URL(fileURLWithPath: filePath)
do {
let data = try String(contentsOf: fileURL, encoding: .ascii)
let cleared = data.components(separatedBy: .whitespacesAndNewlines).joined()

// Search for the application-identifier key and extract its value
if let range = cleared.range(of: "<key>application-identifier</key><string>") {
let substring = cleared[range.upperBound...]
if let endRange = substring.range(of: "</string>") {
let appId = String(substring[..<endRange.lowerBound])
return appId
}
}
} catch {
print("Error reading provisioning profile: \(error)")
return nil
}
return nil
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { UnavailabilityError } from "expo-modules-core";

export default {
isIncorrectAppId(): boolean {
throw new UnavailabilityError("CheckIosAppId", "isIncorrectAppId");
},
getAppId(): string {
throw new UnavailabilityError("CheckIosAppId", "getAppId");
},
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { requireNativeModule } from "expo-modules-core";

interface CheckIosAppIdModule {
isIncorrectAppId(): boolean;
getAppId(): string;
}

// It loads the native module object from the JSI or falls back to
// the bridge module (from NativeModulesProxy) if the remote debugger is on.
export default requireNativeModule("CheckIosCertificate");
export default requireNativeModule("CheckIosAppId") as CheckIosAppIdModule;

This file was deleted.

11 changes: 0 additions & 11 deletions apps/expo/modules/check-ios-certificate/index.ts

This file was deleted.

This file was deleted.

This file was deleted.

20 changes: 2 additions & 18 deletions apps/expo/modules/check-ios-marketplace/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
import type { MarketplaceSource } from "./src/CheckIosMarketplaceModule";
import CheckIosMarketplaceModule from "./src/CheckIosMarketplaceModule";

export enum MarketplaceSource {
AppStore = "App Store",
TestFlight = "TestFlight",
Marketplace = "Alternative marketplace",
Web = "Website",
Other = "Other",
Unknown = "Unknown",
Error = "Error",
Unavailable = "Unavailable",
}

interface CheckIosMarketplaceModule {
getCurrentMarketplaceAsync(): Promise<MarketplaceSource>;
}

export async function getCurrentMarketplaceAsync(): Promise<MarketplaceSource> {
return (
CheckIosMarketplaceModule as CheckIosMarketplaceModule
).getCurrentMarketplaceAsync();
return CheckIosMarketplaceModule.getCurrentMarketplaceAsync();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import { requireNativeModule } from "expo-modules-core";

export enum MarketplaceSource {
AppStore = "App Store",
TestFlight = "TestFlight",
Marketplace = "Alternative marketplace",
Web = "Website",
Other = "Other",
Unknown = "Unknown",
Error = "Error",
Unavailable = "Unavailable",
}

interface CheckIosMarketplaceModule {
getCurrentMarketplaceAsync(): Promise<MarketplaceSource>;
}

// It loads the native module object from the JSI or falls back to
// the bridge module (from NativeModulesProxy) if the remote debugger is on.
export default requireNativeModule("CheckIosMarketplace");
export default requireNativeModule(
"CheckIosMarketplace",
) as CheckIosMarketplaceModule;
2 changes: 1 addition & 1 deletion apps/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"android": "expo run:android",
"ios": "expo run:ios",
"apk": "expo prebuild --platform=android && cd android && ./gradlew assembleRelease && mv app/build/outputs/apk/release/app-release.apk app/build/movie-web.apk",
"ipa": "expo prebuild --platform=ios && cd ios && xcodebuild clean archive -workspace movieweb.xcworkspace -scheme movieweb -configuration Release -destination generic/platform=iOS -archivePath build/movieweb.xcarchive CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_ALLOWED=NO | xcbeautify && cd build/movieweb.xcarchive/Products && mv Applications Payload && zip -r movie-web.ipa Payload && mv movie-web.ipa ../..",
"ipa": "expo prebuild --platform=ios && cd ios && xcodebuild archive -workspace movieweb.xcworkspace -scheme movieweb -configuration Release -destination generic/platform=iOS -archivePath build/movieweb.xcarchive CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_ALLOWED=NO | xcbeautify && cd build/movieweb.xcarchive/Products && mv Applications Payload && zip -r movie-web.ipa Payload && mv movie-web.ipa ../..",
"ipa:sim": "expo prebuild --platform=ios && cd ios && xcodebuild clean archive -workspace movieweb.xcworkspace -scheme movieweb -configuration Release -destination \"generic/platform=iOS Simulator\" -archivePath build/movieweb.xcarchive CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_ALLOWED=NO | xcbeautify && cd build/movieweb.xcarchive/Products && mv Applications Payload && zip -r movie-web.ipa Payload && mv movie-web.ipa ../..",
"format": "prettier --check . --ignore-path ../../.gitignore",
"lint": "eslint .",
Expand Down
19 changes: 8 additions & 11 deletions apps/expo/src/app/(tabs)/downloads.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { Alert, Platform } from "react-native";
import { useFocusEffect, useRouter } from "expo-router";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { isDevelopmentProvisioningProfile } from "modules/check-ios-certificate";
import { getAppId, isIncorrectAppId } from "modules/check-ios-app-id";
import { ScrollView, useTheme, YStack } from "tamagui";

import type { ScrapeMedia } from "@movie-web/provider-utils";
Expand Down Expand Up @@ -81,10 +81,11 @@ const DownloadsScreen: React.FC = () => {

useFocusEffect(
React.useCallback(() => {
if (Platform.OS === "ios" && !isDevelopmentProvisioningProfile()) {
if (Platform.OS === "ios" && isIncorrectAppId()) {
const appId = getAppId();
Alert.alert(
"Production Certificate",
"Download functionality is not available when the application is signed with a distribution certificate.",
"Wildcard/Mismatching App ID",
`The application is signed with a wildcard or mismatching App ID (${appId}). Download functionality is not available when the application is signed with a wildcard or mismatching App ID.`,
[
{
text: "OK",
Expand Down Expand Up @@ -148,14 +149,10 @@ const DownloadsScreen: React.FC = () => {
onPress={() => handlePress(download.downloads[0]!.localPath)}
/>
);
} else {
return (
<ShowDownloadItem
key={download.media.tmdbId}
download={download}
/>
);
}
return (
<ShowDownloadItem key={download.media.tmdbId} download={download} />
);
})}
</ScrollView>
</ScreenLayout>
Expand Down
14 changes: 6 additions & 8 deletions apps/expo/src/components/player/BottomControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Animated, {
useSharedValue,
withTiming,
} from "react-native-reanimated";
import { isDevelopmentProvisioningProfile } from "modules/check-ios-certificate";
import { isIncorrectAppId } from "modules/check-ios-app-id";
import { Text, View } from "tamagui";
import { LinearGradient } from "tamagui/linear-gradient";

Expand Down Expand Up @@ -39,12 +39,11 @@ export const BottomControls = () => {
(player.duration ?? 0) - (player.currentTime ?? 0),
)}`;
return { currentTime: current, remainingTime: remaining };
} else {
return {
currentTime: mapSecondsToTime(0),
remainingTime: mapSecondsToTime(0),
};
}
return {
currentTime: mapSecondsToTime(0),
remainingTime: mapSecondsToTime(0),
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [player?.currentTime]);

Expand Down Expand Up @@ -110,8 +109,7 @@ export const BottomControls = () => {
<AudioTrackSelector />
<SettingsSelector />
{Platform.OS === "android" ||
(Platform.OS === "ios" &&
isDevelopmentProvisioningProfile()) ? (
(Platform.OS === "ios" && !isIncorrectAppId()) ? (
<DownloadButton />
) : null}
</>
Expand Down

0 comments on commit ad83de9

Please sign in to comment.