diff --git a/src/routes/likernft/sell.ts b/src/routes/likernft/sell.ts index 5b27b500e..7e75f0b9b 100644 --- a/src/routes/likernft/sell.ts +++ b/src/routes/likernft/sell.ts @@ -29,10 +29,12 @@ router.post( const info = await getNFTTransferInfo(txHash, classId, nftId); if (!info) throw new ValidationError('NO_MATCHING_TX_HASH_AND_NFT_ID'); const { + code, fromAddress, toAddress, txTimestamp, } = info; + if (code) throw new ValidationError(`TX_FAILED_WITH_CODE_${code}`); if (toAddress !== LIKER_NFT_TARGET_ADDRESS) throw new ValidationError('INVALID_TX_RECEIVER'); const iscnPrefix = await getISCNPrefixByClassId(classId); const owner = await getNFTOwner(classId, nftId); diff --git a/src/routes/likernft/transfer.ts b/src/routes/likernft/transfer.ts index 07db517b7..b023576a8 100644 --- a/src/routes/likernft/transfer.ts +++ b/src/routes/likernft/transfer.ts @@ -21,10 +21,12 @@ router.post( const info = await getNFTTransferInfo(txHash, classId, nftId); if (!info) throw new ValidationError('NO_MATCHING_TX_HASH_AND_NFT_ID'); const { + code, fromAddress, toAddress, txTimestamp, } = info; + if (code) throw new ValidationError(`TX_FAILED_WITH_CODE_${code}`); const iscnPrefix = await getISCNPrefixByClassId(classId); await processNFTTransfer({ fromAddress, diff --git a/src/routes/users/registerLogin.ts b/src/routes/users/registerLogin.ts index 950656c40..b49c51e6a 100644 --- a/src/routes/users/registerLogin.ts +++ b/src/routes/users/registerLogin.ts @@ -355,9 +355,13 @@ router.post( const { avatarSHA256 } = req.body; const { file } = req; let avatarUrl; + let avatarHash; if (!file) throw new ValidationError('MISSING_AVATAR_FILE'); try { - avatarUrl = await handleAvatarUploadAndGetURL(user, file, avatarSHA256); + ({ + url: avatarUrl, + hash: avatarHash, + } = await handleAvatarUploadAndGetURL(user, file, avatarSHA256)); } catch (err) { // eslint-disable-next-line no-console console.error('Avatar file handling error:'); @@ -366,7 +370,9 @@ router.post( throw new ValidationError('INVALID_AVATAR'); } - await dbRef.doc(user).update({ avatar: avatarUrl }); + const payload = { avatar: avatarUrl }; + if (avatarHash) payload.avatarHash = avatarHash; + await dbRef.doc(user).update(payload); res.json({ avatar: avatarUrl }); const oldUserObj = await dbRef.doc(user).get(); diff --git a/src/util/api/likernft/transfer.ts b/src/util/api/likernft/transfer.ts index 6ffb321ec..89bd0976b 100644 --- a/src/util/api/likernft/transfer.ts +++ b/src/util/api/likernft/transfer.ts @@ -16,8 +16,9 @@ export async function getNFTTransferInfo(txHash, classId, nftId) { sender: fromAddress, receiver: toAddress, } = message; - const { timestamp } = data.tx_response; + const { code, timestamp } = data.tx_response; return { + code, fromAddress, toAddress, txTimestamp: Date.parse(timestamp), diff --git a/src/util/api/users/getPublicInfo.ts b/src/util/api/users/getPublicInfo.ts index 06548a617..0a0558a4b 100644 --- a/src/util/api/users/getPublicInfo.ts +++ b/src/util/api/users/getPublicInfo.ts @@ -28,10 +28,12 @@ function isValidUserDoc(userDoc) { function formatUserCivicLikerProperies(userDoc) { const { id } = userDoc; const data = userDoc.data(); - const { civicLiker } = data; + const { civicLiker, avatarHash } = data; const payload = data; payload.user = id; - payload.avatar = `https://${API_EXTERNAL_HOSTNAME}/users/id/${id}/avatar?size=${DEFAULT_AVATAR_SIZE}`; + let avatarUrl = `https://${API_EXTERNAL_HOSTNAME}/users/id/${id}/avatar?size=${DEFAULT_AVATAR_SIZE}`; + if (avatarHash) avatarUrl += `&hash=${avatarHash}`; + payload.avatar = avatarUrl; if (civicLiker) { const { diff --git a/src/util/api/users/register.ts b/src/util/api/users/register.ts index 1148788d6..73fa5c555 100644 --- a/src/util/api/users/register.ts +++ b/src/util/api/users/register.ts @@ -129,9 +129,13 @@ export async function handleUserRegistration({ // upload avatar const { file } = req; let avatarURL; + let avatarHash; try { if (file) { - avatarURL = await handleAvatarUploadAndGetURL(user, file, avatarSHA256); + ({ + url: avatarURL, + hash: avatarHash, + } = await handleAvatarUploadAndGetURL(user, file, avatarSHA256)); } else if (avatarURLInput) { avatarURL = await handleAvatarLinkAndGetURL(user, avatarURLInput); } @@ -170,7 +174,10 @@ export async function handleUserRegistration({ locale, }; - if (avatarURL) createObj.avatar = avatarURL; + if (avatarURL) { + createObj.avatar = avatarURL; + if (avatarHash) createObj.avatarHash = avatarHash; + } if (likeWallet) createObj.likeWallet = likeWallet; if (hasReferrer) createObj.referrer = referrer; if (description) createObj.description = description; diff --git a/src/util/fileupload.ts b/src/util/fileupload.ts index 3858556b5..4a961da4c 100644 --- a/src/util/fileupload.ts +++ b/src/util/fileupload.ts @@ -52,8 +52,8 @@ export async function handleAvatarUploadAndGetURL(user, file, avatarSHA256) { throw new ValidationError(`unsupported file format! ${(type || {}).ext || JSON.stringify(type)}`); } + const hash256 = sha256(file.buffer); if (avatarSHA256) { - const hash256 = sha256(file.buffer); if (hash256 !== avatarSHA256) throw new ValidationError('avatar sha not match'); } @@ -64,7 +64,7 @@ export async function handleAvatarUploadAndGetURL(user, file, avatarSHA256) { mimetype: file.mimetype, }); const versionHash = md5(file.buffer).substring(0, 7); - return `${avatarUrl}&${versionHash}`; + return { url: `${avatarUrl}&${versionHash}`, hash: hash256 }; } export async function handleAvatarLinkAndGetURL(user, url) { diff --git a/test/stub/util/fileupload.ts b/test/stub/util/fileupload.ts index b891856bd..6ef602244 100644 --- a/test/stub/util/fileupload.ts +++ b/test/stub/util/fileupload.ts @@ -25,8 +25,8 @@ export async function handleAvatarUploadAndGetURL(user, file, avatarSHA256) { throw new ValidationError(`unsupported file format! ${(type || {}).ext || JSON.stringify(type)}`); } + const hash256 = sha256(file.buffer); if (avatarSHA256) { - const hash256 = sha256(file.buffer); if (hash256 !== avatarSHA256) throw new ValidationError('avatar sha not match'); } @@ -34,7 +34,7 @@ export async function handleAvatarUploadAndGetURL(user, file, avatarSHA256) { file.buffer = resizedBuffer; // eslint-disable-line no-param-reassign const [avatarUrl] = uploadFileAndGetLink(); const versionHash = md5(file.buffer).substring(0, 7); - return `${avatarUrl}&${versionHash}`; + return { url: `${avatarUrl}&${versionHash}`, hash: hash256 }; } export async function handleAvatarLinkAndGetURL(user, url) {