Migrate from .NET MAUI to Expo + Convex
Complete rewrite of Scry using TypeScript stack:
- Expo/React Native with Expo Router (file-based routing)
- Convex backend (serverless functions + real-time database)
- Adaptive camera system (expo-camera in Expo Go, Vision Camera in production)
- React Native Skia + fast-opencv for image processing
- GDPR-compliant auth setup with Zitadel OIDC (pending configuration)
Key features:
- Card recognition pipeline ported to TypeScript
- Perceptual hashing (192-bit color pHash)
- CLAHE preprocessing for lighting normalization
- Local SQLite cache with Convex sync
- Collection management with offline support
Removes all .NET/MAUI code (src/, test/, tools/).
💘 Generated with Crush
Assisted-by: Claude Opus 4.5 via Crush <crush@charm.land>
This commit is contained in:
parent
56499d5af9
commit
83ab4df537
138 changed files with 19136 additions and 7681 deletions
48
convex/auth.ts
Normal file
48
convex/auth.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Convex Auth configuration with Zitadel OIDC.
|
||||
*
|
||||
* GDPR Compliance: No user profile data (name, email, image) is stored.
|
||||
* User details must be fetched from Zitadel userinfo endpoint when needed.
|
||||
*/
|
||||
|
||||
import Zitadel from "@auth/core/providers/zitadel";
|
||||
import { convexAuth } from "@convex-dev/auth/server";
|
||||
|
||||
export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
|
||||
providers: [
|
||||
Zitadel({
|
||||
issuer: process.env.AUTH_ZITADEL_ISSUER,
|
||||
clientId: process.env.AUTH_ZITADEL_ID,
|
||||
clientSecret: process.env.AUTH_ZITADEL_SECRET,
|
||||
// Strip all profile data - return only the subject ID
|
||||
profile(zitadelProfile) {
|
||||
return {
|
||||
id: zitadelProfile.sub,
|
||||
// Intentionally omit: name, email, image
|
||||
// These must be fetched from Zitadel userinfo endpoint
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
// Validate redirect URIs for React Native
|
||||
async redirect({ redirectTo }) {
|
||||
const allowedPrefixes = [
|
||||
"scry://", // App custom scheme
|
||||
"app://", // Default Expo scheme
|
||||
"exp://", // Expo Go
|
||||
"http://localhost",
|
||||
"https://localhost",
|
||||
];
|
||||
|
||||
const isAllowed = allowedPrefixes.some((prefix) =>
|
||||
redirectTo.startsWith(prefix)
|
||||
);
|
||||
|
||||
if (!isAllowed) {
|
||||
throw new Error(`Invalid redirectTo URI: ${redirectTo}`);
|
||||
}
|
||||
return redirectTo;
|
||||
},
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue