{"version":3,"sources":["../src/server/db/encrypted-json-db.ts","../src/server/handlers/wallet-auth.ts"],"sourcesContent":["import { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { createCipheriv, createDecipheriv, randomBytes } from 'crypto';\nimport { User, NewUserData } from '../../types';\nimport type { DatabaseInterface } from './interface';\n\ninterface DBSchema {\n    users: User[];\n}\n\nconst defaultSchema: DBSchema = {\n    users: []\n};\n\nexport class EncryptedJSONDatabase implements DatabaseInterface {\n    private static instance: EncryptedJSONDatabase;\n    private dbPath: string;\n    private data: DBSchema = defaultSchema;\n    private initialized: boolean = false;\n    private encryptionKey: Buffer;\n\n    private constructor(dbPath?: string) {\n        this.dbPath = dbPath || join(process.cwd(), 'data', 'caplib-users.encrypted.json');\n        const key = process.env.DB_ENCRYPTION_KEY || randomBytes(32).toString('hex');\n        this.encryptionKey = Buffer.from(key, 'hex');\n    }\n\n    public static getInstance(dbPath?: string): EncryptedJSONDatabase {\n        if (!EncryptedJSONDatabase.instance) {\n            EncryptedJSONDatabase.instance = new EncryptedJSONDatabase(dbPath);\n        }\n        return EncryptedJSONDatabase.instance;\n    }\n\n    private async encrypt(data: string): Promise<string> {\n        const iv = randomBytes(16);\n        const cipher = createCipheriv('aes-256-gcm', this.encryptionKey, iv);\n\n        let encrypted = cipher.update(data, 'utf8', 'hex');\n        encrypted += cipher.final('hex');\n\n        const authTag = cipher.getAuthTag();\n\n        return JSON.stringify({\n            iv: iv.toString('hex'),\n            data: encrypted,\n            authTag: authTag.toString('hex')\n        });\n    }\n\n    private async decrypt(encryptedData: string): Promise<string> {\n        const { iv, data, authTag } = JSON.parse(encryptedData);\n\n        const decipher = createDecipheriv(\n            'aes-256-gcm',\n            this.encryptionKey,\n            Buffer.from(iv, 'hex')\n        );\n\n        decipher.setAuthTag(Buffer.from(authTag, 'hex'));\n\n        let decrypted = decipher.update(data, 'hex', 'utf8');\n        decrypted += decipher.final('utf8');\n\n        return decrypted;\n    }\n\n    private async ensureDirectoryExists(): Promise<void> {\n        const dir = this.dbPath.substring(0, this.dbPath.lastIndexOf('/'));\n        try {\n            await fs.access(dir);\n        } catch {\n            await fs.mkdir(dir, { recursive: true });\n        }\n    }\n\n    private async loadData(): Promise<void> {\n        try {\n            const encryptedContent = await fs.readFile(this.dbPath, 'utf-8');\n            const decryptedContent = await this.decrypt(encryptedContent);\n            this.data = JSON.parse(decryptedContent);\n        } catch (error) {\n            if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n                this.data = defaultSchema;\n                await this.saveData();\n            } else {\n                throw error;\n            }\n        }\n    }\n\n    private async saveData(): Promise<void> {\n        await this.ensureDirectoryExists();\n        const encryptedData = await this.encrypt(JSON.stringify(this.data));\n        await fs.writeFile(this.dbPath, encryptedData);\n    }\n\n    public async initialize(): Promise<void> {\n        if (this.initialized) return;\n\n        try {\n            await this.loadData();\n            this.initialized = true;\n        } catch (error) {\n            console.error('Failed to initialize database:', error);\n            throw error;\n        }\n    }\n\n    public async findUser(walletAddress: string): Promise<User | null> {\n        await this.initialize();\n        const user = this.data.users.find(u =>\n            u.wallet_address.toLowerCase() === walletAddress.toLowerCase()\n        );\n        return user || null;\n    }\n\n    public async createUser(userData: NewUserData): Promise<User> {\n        await this.initialize();\n\n        const existingUser = await this.findUser(userData.wallet_address);\n        if (existingUser) {\n            throw new Error('User already exists');\n        }\n\n        const now = new Date().toISOString();\n        const newUser: User = {\n            ...userData,\n            role: userData.role || 'User',\n            account_type: userData.account_type || 'human',\n            created_at: now\n        };\n\n        this.data.users.push(newUser);\n        await this.saveData();\n\n        return newUser;\n    }\n\n    public async updateUser(walletAddress: string, updates: Partial<User>): Promise<User | null> {\n        await this.initialize();\n\n        const index = this.data.users.findIndex(u =>\n            u.wallet_address.toLowerCase() === walletAddress.toLowerCase()\n        );\n\n        if (index === -1) return null;\n\n        const updatedUser = {\n            ...this.data.users[index],\n            ...updates,\n            wallet_address: this.data.users[index].wallet_address\n        };\n\n        this.data.users[index] = updatedUser;\n        await this.saveData();\n\n        return updatedUser;\n    }\n\n    public async deleteUser(walletAddress: string): Promise<boolean> {\n        await this.initialize();\n\n        const initialLength = this.data.users.length;\n        this.data.users = this.data.users.filter(u =>\n            u.wallet_address.toLowerCase() !== walletAddress.toLowerCase()\n        );\n\n        if (this.data.users.length !== initialLength) {\n            await this.saveData();\n            return true;\n        }\n\n        return false;\n    }\n\n    public async close(): Promise<void> {\n        await this.saveData();\n        this.initialized = false;\n    }\n}","import { NextRequest } from 'next/server';\nimport type { AuthHandlerConfig, AuthResponse, NonceResponse } from '../../types';\nimport { EncryptedJSONDatabase } from '../db/encrypted-json-db';\nimport { isValidRole, getDefaultRole } from '../utils/roles';\n\nconst getEnvVariable = (name: string, fallbackName?: string): string => {\n    let value = process.env[name];\n    if (!value && fallbackName) {\n        value = process.env[fallbackName];\n    }\n\n    if (!value) {\n        throw new Error(`Required environment variable ${name}${fallbackName ? ` or ${fallbackName}` : ''} is not set`);\n    }\n    return value;\n};\n\nexport const createAuthHandler = (config?: AuthHandlerConfig) => {\n    const db = EncryptedJSONDatabase.getInstance();\n    let isInitialized = false;\n\n    const initialize = async () => {\n        if (!isInitialized) {\n            try {\n                await db.initialize();\n                isInitialized = true;\n            } catch (error) {\n                console.error('Failed to initialize database:', error);\n            }\n        }\n    };\n\n    const GET = async (): Promise<Response> => {\n        try {\n            const API_URL = getEnvVariable('CAPLIB_API_URL');\n            const API_KEY = getEnvVariable('CAPLIB_API_KEY');\n            const CONTRACT_ID = getEnvVariable('NEXT_PUBLIC_AUTH_CONTRACT_ID', 'AUTH_CONTRACT_ID');\n\n            await initialize();\n\n            const response = await fetch(`${API_URL}?action=generateNonce&contractId=${CONTRACT_ID}`, {\n                headers: { 'X-API-Key': API_KEY },\n            });\n\n            if (!response.ok) {\n                throw new Error(`HTTP error! status: ${response.status}`);\n            }\n\n            const data = await response.json();\n\n            return new Response(\n                JSON.stringify({ nonce: data.nonce } as NonceResponse),\n                {\n                    status: 200,\n                    headers: { 'Content-Type': 'application/json' },\n                }\n            );\n        } catch (error) {\n            console.error('Error generating nonce:', error);\n\n            return new Response(\n                JSON.stringify({ error: 'Failed to generate nonce', nonce: '' } as NonceResponse),\n                {\n                    status: 500,\n                    headers: { 'Content-Type': 'application/json' },\n                }\n            );\n        }\n    };\n\n    const POST = async (req: NextRequest): Promise<Response> => {\n        try {\n            const API_URL = getEnvVariable('CAPLIB_API_URL');\n            const API_KEY = getEnvVariable('CAPLIB_API_KEY');\n            const CONTRACT_ID = getEnvVariable('NEXT_PUBLIC_AUTH_CONTRACT_ID', 'AUTH_CONTRACT_ID');\n\n            await initialize();\n\n            const body = await req.json();\n            const { nonce, userData } = body;\n\n            const verifyResponse = await fetch(API_URL, {\n                method: 'POST',\n                headers: {\n                    'X-API-Key': API_KEY,\n                    'Content-Type': 'application/json'\n                },\n                body: JSON.stringify({\n                    action: 'verifyAuthentication',\n                    contractId: CONTRACT_ID,\n                    nonce: nonce,\n                }),\n            });\n\n            if (!verifyResponse.ok) {\n                throw new Error(`Verification failed: ${verifyResponse.status}`);\n            }\n\n            const verifyData = await verifyResponse.json();\n            const { authenticated, userAddress } = verifyData;\n\n            if (!authenticated || !userAddress) {\n                return new Response(\n                    JSON.stringify({\n                        authenticated: false,\n                        error: 'Authentication failed'\n                    } as AuthResponse),\n                    {\n                        status: 401,\n                        headers: { 'Content-Type': 'application/json' },\n                    }\n                );\n            }\n\n            if (config?.customValidation) {\n                const isValid = await config.customValidation(userAddress);\n                if (!isValid) {\n                    return new Response(\n                        JSON.stringify({\n                            authenticated: false,\n                            error: 'Custom validation failed'\n                        } as AuthResponse),\n                        {\n                            status: 403,\n                            headers: { 'Content-Type': 'application/json' },\n                        }\n                    );\n                }\n            }\n\n            try {\n                let user = await db.findUser(userAddress);\n\n                if (userData?.role && !isValidRole(userData.role)) {\n                    userData.role = getDefaultRole();\n                  }\n                  \n                if (!user && userData) {\n                    user = await db.createUser({\n                        wallet_address: userAddress,\n                        ...userData\n                    });\n                }\n\n                return new Response(\n                    JSON.stringify({\n                        authenticated: true,\n                        userAddress,\n                        user: user || undefined\n                    } as AuthResponse),\n                    {\n                        status: 200,\n                        headers: { 'Content-Type': 'application/json' },\n                    }\n                );\n            } catch (error) {\n                console.error('Database error:', error);\n                return new Response(\n                    JSON.stringify({\n                        authenticated: true,\n                        userAddress,\n                        error: 'Database operation failed'\n                    } as AuthResponse),\n                    {\n                        status: 200,\n                        headers: { 'Content-Type': 'application/json' },\n                    }\n                );\n            }\n        } catch (error) {\n            console.error('Error verifying authentication:', error);\n\n            return new Response(\n                JSON.stringify({\n                    authenticated: false,\n                    error: 'Authentication verification failed'\n                } as AuthResponse),\n                {\n                    status: 500,\n                    headers: { 'Content-Type': 'application/json' },\n                }\n            );\n        }\n    };\n\n    return { GET, POST };\n};"],"mappings":"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","names":[]}