Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions backend/src/routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,17 @@ router.post('/sep10', sep10Limiter, validate(sep10Schema), async (req, res) => {
* 429:
* description: Rate limit exceeded (max 10 requests per IP per minute)
*/
router.post('/verify', sep10VerifyLimiter, validate(verifySchema), bruteForceGuard, (req, res) => {
const { transaction, nonce } = req.body;
const { isAuthorizedIssuer } = require('../middleware/issuer');

router.post('/verify', sep10VerifyLimiter, validate(verifySchema), bruteForceGuard, async (req, res) => {
const { transaction, signed_tx, nonce } = req.body;
const tx = transaction || signed_tx;
const ip = req.ip || req.socket?.remoteAddress || 'unknown';

try {
const publicKey = verifyChallenge(transaction, nonce);

const role = publicKey === process.env.ADMIN_PUBLIC_KEY ? 'admin' : 'patient';
const publicKey = verifyChallenge(tx, nonce);
const isIssuer = await isAuthorizedIssuer(publicKey);
const role = isIssuer ? 'issuer' : 'patient';
const now = Math.floor(Date.now() / 1000);
const signingKey = getSigningKey();

Expand All @@ -145,11 +148,10 @@ router.post('/verify', sep10VerifyLimiter, validate(verifySchema), bruteForceGua
// Attempt to extract wallet from the transaction for per-wallet tracking
let wallet = null;
try {
const tx = StellarSdk.TransactionBuilder.fromXDR(transaction, process.env.STELLAR_NETWORK_PASSPHRASE || 'Test SDF Network ; September 2015');
wallet = tx.source;
const txObj = StellarSdk.TransactionBuilder.fromXDR(transaction, process.env.STELLAR_NETWORK_PASSPHRASE || 'Test SDF Network ; September 2015');
wallet = txObj.source;
} catch (_) { /* ignore parse errors */ }

const ip = req.ip || req.socket?.remoteAddress || 'unknown';
recordFailure(`ip:${ip}`, { ip, wallet });
if (wallet) recordFailure(`wallet:${wallet}`, { ip, wallet });

Expand Down
20 changes: 3 additions & 17 deletions backend/src/routes/vaccination.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,26 +281,12 @@ router.post(
router.get('/:wallet', authMiddleware, validateStellarPublicKey('params', 'wallet'), async (req, res) => {
const { wallet } = req.params;

const rawPage = req.query.page !== undefined ? Number(req.query.page) : 1;
const rawLimit = req.query.limit !== undefined ? Number(req.query.limit) : 20;

if (!Number.isInteger(rawPage) || rawPage < 1) {
return res.status(400).json({ error: 'page must be a positive integer' });
}
if (!Number.isInteger(rawLimit) || rawLimit < 1 || rawLimit > 100) {
return res.status(400).json({ error: 'limit must be an integer between 1 and 100' });
}

try {
const args = [StellarSdk.Address.fromString(wallet).toScVal()];
const result = await simulateContract('verify_vaccination', args);
const [vaccinated, allRecords] = StellarSdk.scValToNative(result);

const total = allRecords.length;
const start = (rawPage - 1) * rawLimit;
const data = allRecords.slice(start, start + rawLimit);

res.json({ data, total, page: rawPage, limit: rawLimit });
const [, allRecords] = StellarSdk.scValToNative(result);
const records = Array.isArray(allRecords) ? allRecords : [];
res.json({ wallet, records });
} catch (err) {
if (err instanceof SorobanTimeoutError) return sendRpcTimeout(res);
const errorMessage = resolveContractErrorMessage(err);
Expand Down