mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 07:08:10 -05:00
* add iOS qrcode opener and aadhaar screen * format * fix test * add Image-picker android (#1077) * add image-picker android * fix validation * feat: implement Aadhaar upload success and error screens, enhance AadhaarNavBar with dynamic progress indication - Added AadhaarUploadedSuccessScreen and AadhaarUploadErrorScreen components for handling upload outcomes. - Updated AadhaarNavBar to reflect current upload step with dynamic progress bar. - Integrated new screens into navigation flow for Aadhaar upload process. - Introduced blue check and warning SVG icons for visual feedback on success and error states. * feat: generate mock aadhar (#1083) * feat: generate mock aadhar * add yarn.lock * update yarn.lock * update protocolStore, update types, start modifying provingMachine * Register mock aadhar (#1093) * Register mock aadhar * fix ofac * temp: generate name * fix dob * Add Aadhaar support to ID card component and screens - Integrated Aadhaar icon and conditional rendering in IdCardLayout. - Updated AadhaarUploadScreen to process QR codes and store Aadhaar data. - Modified navigation and button text in AadhaarUploadedSuccessScreen. - Added mock data generation for Aadhaar in the mobile SDK. - Updated ManageDocumentsScreen to include Aadhaar document type. - Enhanced error handling and validation for Aadhaar QR code processing. - Added utility functions for Aadhaar data extraction and commitment processing. * aadhaar disclose - wip (#1094) * fix: timestamp cal of extractQRDataFields * Feat/aadhar fixes (#1099) * Fix - android aadhar qr scanner * fixes * update text * yarn nice * run prettier * Add mock Aadhaar certificates for development - Introduced hardcoded Aadhaar test certificates for development purposes. - Moved Aadhaar mock private and public keys to a dedicated file for better organization. - Updated the mock ID document generation utility to utilize the new Aadhaar mock certificates. * prettier write * add 'add-aadhaar' button (#1100) * Update .gitleaks.toml to include path for mock certificates in the common/dist directory * yarn nice * Enhance Aadhaar error handling with specific error types - Updated the AadhaarUploadErrorScreen to display different messages based on the error type (general or expired). - Modified the AadhaarUploadScreen to pass the appropriate error type when navigating to the error screen. - Set initial parameters for the home screen to include a default error type. * Update passport handling in proving machine to support Aadhaar document category - Modified the handling of country code in the useProvingStore to return 'IND' for Aadhaar documents. - Ensured that the country code is only fetched from passport metadata for non-Aadhaar documents. * tweak layout, text, change email to support, hide help button * fix ci, remove aadhaar logging, add aadhaar events * remove unused aadhaar tracking events * update globs * fix gitguardian config * don't track id --------- Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz> Co-authored-by: Seshanth.S🐺 <35675963+seshanthS@users.noreply.github.com> Co-authored-by: vishal <vishalkoolkarni0045@gmail.com>
153 lines
4.4 KiB
Swift
153 lines
4.4 KiB
Swift
//
|
|
// PhotoLibraryQRScannerViewController.swift
|
|
// Self
|
|
//
|
|
// Created by Rémi Colin on 09/09/2025.
|
|
//
|
|
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11
|
|
|
|
//
|
|
// PhotoLibraryQRScannerViewController.swift
|
|
// OpenPassport
|
|
//
|
|
// Created by AI Assistant on 01/03/2025.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import CoreImage
|
|
import Photos
|
|
|
|
class PhotoLibraryQRScannerViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
|
var completionHandler: ((String) -> Void)?
|
|
var errorHandler: ((Error) -> Void)?
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
checkPhotoLibraryPermissionAndPresentPicker()
|
|
}
|
|
|
|
private func checkPhotoLibraryPermissionAndPresentPicker() {
|
|
let status = PHPhotoLibrary.authorizationStatus()
|
|
|
|
switch status {
|
|
case .authorized, .limited:
|
|
presentImagePicker()
|
|
case .notDetermined:
|
|
PHPhotoLibrary.requestAuthorization { [weak self] status in
|
|
DispatchQueue.main.async {
|
|
if status == .authorized || status == .limited {
|
|
self?.presentImagePicker()
|
|
} else {
|
|
self?.handlePermissionDenied()
|
|
}
|
|
}
|
|
}
|
|
case .denied, .restricted:
|
|
handlePermissionDenied()
|
|
@unknown default:
|
|
handlePermissionDenied()
|
|
}
|
|
}
|
|
|
|
private func presentImagePicker() {
|
|
let imagePicker = UIImagePickerController()
|
|
imagePicker.delegate = self
|
|
imagePicker.sourceType = .photoLibrary
|
|
imagePicker.mediaTypes = ["public.image"]
|
|
present(imagePicker, animated: true, completion: nil)
|
|
}
|
|
|
|
private func handlePermissionDenied() {
|
|
let error = NSError(
|
|
domain: "QRScannerError",
|
|
code: 1001,
|
|
userInfo: [NSLocalizedDescriptionKey: "Photo library access is required to scan QR codes from photos. Please enable access in Settings."]
|
|
)
|
|
errorHandler?(error)
|
|
dismiss(animated: true, completion: nil)
|
|
}
|
|
|
|
// MARK: - UIImagePickerControllerDelegate
|
|
|
|
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
|
|
picker.dismiss(animated: true) { [weak self] in
|
|
guard let self = self else { return }
|
|
|
|
if let selectedImage = info[.originalImage] as? UIImage {
|
|
self.detectQRCode(in: selectedImage)
|
|
} else {
|
|
let error = NSError(
|
|
domain: "QRScannerError",
|
|
code: 1002,
|
|
userInfo: [NSLocalizedDescriptionKey: "Failed to load the selected image."]
|
|
)
|
|
self.errorHandler?(error)
|
|
self.dismiss(animated: true, completion: nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
|
picker.dismiss(animated: true) { [weak self] in
|
|
let error = NSError(
|
|
domain: "QRScannerError",
|
|
code: 1003,
|
|
userInfo: [NSLocalizedDescriptionKey: "User cancelled photo selection."]
|
|
)
|
|
self?.errorHandler?(error)
|
|
self?.dismiss(animated: true, completion: nil)
|
|
}
|
|
}
|
|
|
|
// MARK: - QR Code Detection
|
|
|
|
private func detectQRCode(in image: UIImage) {
|
|
guard let ciImage = CIImage(image: image) else {
|
|
let error = NSError(
|
|
domain: "QRScannerError",
|
|
code: 1004,
|
|
userInfo: [NSLocalizedDescriptionKey: "Failed to process the selected image."]
|
|
)
|
|
errorHandler?(error)
|
|
dismiss(animated: true, completion: nil)
|
|
return
|
|
}
|
|
|
|
let detector = CIDetector(
|
|
ofType: CIDetectorTypeQRCode,
|
|
context: nil,
|
|
options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]
|
|
)
|
|
|
|
guard let detector = detector else {
|
|
let error = NSError(
|
|
domain: "QRScannerError",
|
|
code: 1005,
|
|
userInfo: [NSLocalizedDescriptionKey: "Failed to initialize QR code detector."]
|
|
)
|
|
errorHandler?(error)
|
|
dismiss(animated: true, completion: nil)
|
|
return
|
|
}
|
|
|
|
let features = detector.features(in: ciImage) as? [CIQRCodeFeature] ?? []
|
|
|
|
if let firstQRCode = features.first, let qrCodeString = firstQRCode.messageString {
|
|
completionHandler?(qrCodeString)
|
|
dismiss(animated: true, completion: nil)
|
|
} else {
|
|
let error = NSError(
|
|
domain: "QRScannerError",
|
|
code: 1006,
|
|
userInfo: [NSLocalizedDescriptionKey: "No QR code found in the selected image. Please try with a different image."]
|
|
)
|
|
errorHandler?(error)
|
|
dismiss(animated: true, completion: nil)
|
|
}
|
|
}
|
|
}
|
|
|