diff --git a/src/App/App.csproj b/src/App/App.csproj index 371c5fcc2..f5bb98ce8 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -64,6 +64,9 @@ CollectionsPage.xaml + + ScanPage.xaml + SharePage.xaml diff --git a/src/App/Pages/Vault/ScanPage.xaml b/src/App/Pages/Vault/ScanPage.xaml new file mode 100644 index 000000000..e3f6c7ef0 --- /dev/null +++ b/src/App/Pages/Vault/ScanPage.xaml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/App/Pages/Vault/ScanPage.xaml.cs b/src/App/Pages/Vault/ScanPage.xaml.cs new file mode 100644 index 000000000..4937dd88d --- /dev/null +++ b/src/App/Pages/Vault/ScanPage.xaml.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using Xamarin.Forms; + +namespace Bit.App.Pages +{ + public partial class ScanPage : BaseContentPage + { + private readonly Action _callback; + + private DateTime? _timerStarted = null; + private TimeSpan _timerMaxLength = TimeSpan.FromMinutes(3); + + public ScanPage(Action callback) + { + _callback = callback; + _zxing.Options = new ZXing.Mobile.MobileBarcodeScanningOptions + { + UseNativeScanning = true, + PossibleFormats = new List { ZXing.BarcodeFormat.QR_CODE }, + AutoRotate = false, + }; + InitializeComponent(); + } + + protected override void OnAppearing() + { + base.OnAppearing(); + _zxing.IsScanning = true; + _timerStarted = DateTime.Now; + Device.StartTimer(new TimeSpan(0, 0, 2), () => + { + if(_timerStarted == null || (DateTime.Now - _timerStarted) > _timerMaxLength) + { + return false; + } + _zxing.AutoFocus(); + return true; + }); + } + + protected override void OnDisappearing() + { + _timerStarted = null; + _zxing.IsScanning = false; + base.OnDisappearing(); + } + + private void OnScanResult(ZXing.Result result) + { + // Stop analysis until we navigate away so we don't keep reading barcodes + _zxing.IsAnalyzing = false; + _zxing.IsScanning = false; + if(!string.IsNullOrWhiteSpace(result?.Text) && + Uri.TryCreate(result.Text, UriKind.Absolute, out Uri uri) && + !string.IsNullOrWhiteSpace(uri?.Query)) + { + var queryParts = uri.Query.Substring(1).ToLowerInvariant().Split('&'); + foreach(var part in queryParts) + { + if(part.StartsWith("secret=")) + { + _callback(part.Substring(7)?.ToUpperInvariant()); + return; + } + } + } + _callback(null); + } + } +}