Skip to content

Commit

Permalink
t
Browse files Browse the repository at this point in the history
  • Loading branch information
IZUMI-Zu committed Aug 24, 2024
1 parent db5df2a commit 2cbe759
Show file tree
Hide file tree
Showing 7 changed files with 732 additions and 124 deletions.
55 changes: 49 additions & 6 deletions ScanQRCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {Text, View} from "react-native";
import {IconButton, Portal} from "react-native-paper";
import {Camera, CameraView} from "expo-camera";
import PropTypes from "prop-types";
import useProtobufDecoder from "./useProtobufDecoder";

const ScanQRCode = ({onClose, showScanner, onAdd}) => {
ScanQRCode.propTypes = {
Expand All @@ -26,6 +27,7 @@ const ScanQRCode = ({onClose, showScanner, onAdd}) => {
};

const [hasPermission, setHasPermission] = useState(null);
const decoder = useProtobufDecoder(require("./google/google_auth.proto"));

useEffect(() => {
const getCameraPermissions = async() => {
Expand All @@ -41,17 +43,58 @@ const ScanQRCode = ({onClose, showScanner, onAdd}) => {
};

const handleBarCodeScanned = ({type, data}) => {
// type org.iso.QRCode
// data otpauth://totp/casdoor:built-in/admin?algorithm=SHA1&digits=6&issuer=casdoor&period=30&secret=DL5XI33M772GSGU73GJPCOIBNJE7TG3J
// console.log(`Bar code with type ${type} and data ${data} has been scanned!`);
const accountName = data.match(/otpauth:\/\/totp\/([^?]+)/); // accountName casdoor:built-in/admin
const secretKey = data.match(/secret=([^&]+)/); // secretKey II5UO7HIA3SPVXAB6KPAIXZ33AQP7C3R

// 定义支持的协议
const supportedProtocols = ["otpauth", "otpauth-migration"];

// 使用正则表达式匹配支持的协议
const protocolMatch = data.match(new RegExp(`^(${supportedProtocols.join("|")}):`));

if (protocolMatch) {
const protocol = protocolMatch[1];
switch (protocol) {
case "otpauth":
handleOtpAuth(data);
break;
case "otpauth-migration":
handleGoogleMigration(data);
break;
default:
break;
}
}
closeOptions();
};

const handleOtpAuth = (data) => {
const accountName = data.match(/otpauth:\/\/totp\/([^?]+)/);
const secretKey = data.match(/secret=([^&]+)/);
const issuer = data.match(/issuer=([^&]+)/);

if (accountName && secretKey) {
onAdd({accountName: accountName[1], issuer: issuer[1], secretKey: secretKey[1]});
onAdd({
accountName: accountName[1],
issuer: issuer ? issuer[1] : null,
secretKey: secretKey[1],
});
}
};

closeOptions();
const handleGoogleMigration = (data) => {
try {
const accounts = decoder.decodeExportUri(data);
console.log(accounts);
accounts.forEach(account => {
onAdd({
accountName: account.accountName,
issuer: account.issuer,
secretKey: account.totpSecret.toString("base32"),
});
});
} catch (error) {
console.error("Failed to decode migration payload:", error);
}
};

return (
Expand Down
7 changes: 7 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
"recordAudioAndroid": true
}
],
"expo-asset",
[
"expo-image-picker",
{
"photosPermission": "The app accesses your photos to let you share them with your friends."
}
]
],
"owner": "zzbs"
Expand Down
43 changes: 43 additions & 0 deletions google/google_auth.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
syntax = "proto3";

package google_auth;

message MigrationPayload {
enum Algorithm {
ALGORITHM_UNSPECIFIED = 0;
SHA1 = 1;
SHA256 = 2;
SHA512 = 3;
MD5 = 4;
}

enum DigitCount {
DIGIT_COUNT_UNSPECIFIED = 0;
SIX = 1;
EIGHT = 2;
SEVEN = 3;
}

enum OtpType {
OTP_TYPE_UNSPECIFIED = 0;
HOTP = 1;
TOTP = 2;
}

message OtpParameters {
bytes secret = 1;
string name = 2;
string issuer = 3;
Algorithm algorithm = 4;
DigitCount digits = 5;
OtpType type = 6;
int64 counter = 7;
string unique_id = 8;
}

repeated OtpParameters otp_parameters = 1;
int32 version = 2;
int32 batch_size = 3;
int32 batch_index = 4;
int32 batch_id = 5;
}
1 change: 1 addition & 0 deletions metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ const {getDefaultConfig} = require("expo/metro-config");
const config = getDefaultConfig(__dirname);

config.resolver.sourceExts.push("sql");
config.resolver.assetExts.push("proto");

module.exports = config;
Loading

0 comments on commit 2cbe759

Please sign in to comment.