Skip to content

Commit

Permalink
Merge pull request #33 from DIG-Network/release/v0.0.1-alpha.36
Browse files Browse the repository at this point in the history
Release/v0.0.1 alpha.36
  • Loading branch information
MichaelTaylor3D authored Sep 22, 2024
2 parents 4ab70b5 + 3c35dc0 commit a52fec3
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 28 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [0.0.1-alpha.36](https://github.com/DIG-Network/dig-propagation-server/compare/v0.0.1-alpha.35...v0.0.1-alpha.36) (2024-09-22)


### Bug Fixes

* nonce logic ([ce53807](https://github.com/DIG-Network/dig-propagation-server/commit/ce53807d118d3ca1d403d26e759b57ec5ad4c0e9))

### [0.0.1-alpha.35](https://github.com/DIG-Network/dig-propagation-server/compare/v0.0.1-alpha.34...v0.0.1-alpha.35) (2024-09-22)


Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dig-propagation-server",
"version": "0.0.1-alpha.35",
"version": "0.0.1-alpha.36",
"description": "",
"type": "commonjs",
"main": "./dist/index.js",
Expand Down
37 changes: 27 additions & 10 deletions src/controllers/merkleTreeController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ export const startUploadSession = async (
* @param {Request} req - The request object.
* @param {Response} res - The response object.
*/
export const generateFileNonce = async (req: Request, res: Response): Promise<void> => {
export const generateFileNonce = async (
req: Request,
res: Response
): Promise<void> => {
try {
const { storeId, sessionId, filename } = req.params;

Expand Down Expand Up @@ -227,6 +230,10 @@ export const uploadFile = async (
);
}

if (validateNonce(`${storeId}_${sessionId}_${filename}`, nonce)) {
throw new HttpError(401, "Invalid nonce.");
}

// Validate the key ownership signature using the nonce
const wallet = await Wallet.load("default");
const isSignatureValid = await wallet.verifyKeyOwnershipSignature(
Expand All @@ -235,10 +242,6 @@ export const uploadFile = async (
publicKey
);

if (validateNonce(`${storeId}_${sessionId}_${filename}`, nonce)) {
throw new HttpError(401, "Invalid nonce.");
}

if (!isSignatureValid) {
console.log("Key ownership signature is invalid.");
throw new HttpError(401, "Invalid key ownership signature.");
Expand Down Expand Up @@ -298,7 +301,10 @@ export const uploadFile = async (
* @param {Request} req - The request object.
* @param {Response} res - The response object.
*/
export const commitUpload = async (req: Request, res: Response): Promise<void> => {
export const commitUpload = async (
req: Request,
res: Response
): Promise<void> => {
try {
const { storeId, sessionId } = req.params;
const finalDir = path.join(digFolderPath, "stores", storeId);
Expand All @@ -317,7 +323,7 @@ export const commitUpload = async (req: Request, res: Response): Promise<void> =
}

// Move all files from the temporary session directory to the final store directory
fs.readdirSync(sessionUploadDir).forEach(file => {
fs.readdirSync(sessionUploadDir).forEach((file) => {
const sourcePath = path.join(sessionUploadDir, file);
const destinationPath = path.join(finalDir, file);
fs.renameSync(sourcePath, destinationPath);
Expand All @@ -326,7 +332,11 @@ export const commitUpload = async (req: Request, res: Response): Promise<void> =
// Clean up the session folder after committing
cleanupSession(sessionId);

res.status(200).json({ message: `Upload for DataStore ${storeId} under session ${sessionId} committed successfully.` });
res
.status(200)
.json({
message: `Upload for DataStore ${storeId} under session ${sessionId} committed successfully.`,
});
} catch (error: any) {
console.error("Error committing upload:", error);
const statusCode = error instanceof HttpError ? error.statusCode : 500;
Expand All @@ -340,7 +350,10 @@ export const commitUpload = async (req: Request, res: Response): Promise<void> =
* @param {Request} req - The request object.
* @param {Response} res - The response object.
*/
export const abortUpload = async (req: Request, res: Response): Promise<void> => {
export const abortUpload = async (
req: Request,
res: Response
): Promise<void> => {
try {
const { storeId, sessionId } = req.params;

Expand All @@ -354,7 +367,11 @@ export const abortUpload = async (req: Request, res: Response): Promise<void> =>
fs.rmSync(session.tmpDir, { recursive: true, force: true });
cleanupSession(sessionId);

res.status(200).json({ message: `Upload session ${sessionId} for DataStore ${storeId} aborted and cleaned up.` });
res
.status(200)
.json({
message: `Upload session ${sessionId} for DataStore ${storeId} aborted and cleaned up.`,
});
} catch (error: any) {
console.error("Error aborting upload session:", error);
const statusCode = error instanceof HttpError ? error.statusCode : 500;
Expand Down
37 changes: 22 additions & 15 deletions src/utils/nonce.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
import crypto from "crypto";
import NodeCache from "node-cache";

// In-memory storage for nonces
const nonceStore: { [userId: string]: { nonce: string; expires: number } } = {};
// Create a new NodeCache instance with a 5-minute TTL for nonces
const nonceCache = new NodeCache({ stdTTL: 5 * 60, checkperiod: 60 }); // Check every minute for expired entries

// Function to generate and store nonce
export const generateNonce = (userId: string): string => {
/**
* Function to generate and store nonce in NodeCache.
* @param {string} userId - Unique identifier for the user (or session).
* @returns {string} - The generated nonce.
*/
export const generateNonce = (nonceKey: string): string => {
const nonce = crypto.randomBytes(16).toString("hex");
const expires = Date.now() + 5 * 60 * 1000; // 5 minutes expiration

nonceStore[userId] = { nonce, expires };
// Store the nonce in the cache with userId as the key
nonceCache.set(nonceKey, nonce);

return nonce;
};

// Function to validate nonce
export const validateNonce = (userId: string, providedNonce: string): boolean => {
const nonceData = nonceStore[userId];
if (!nonceData) return false;

const { nonce, expires } = nonceData;
/**
* Function to validate the provided nonce.
* @param {string} userId - Unique identifier for the user (or session).
* @param {string} providedNonce - The nonce provided for validation.
* @returns {boolean} - True if the nonce is valid, otherwise false.
*/
export const validateNonce = (nonceKey: string, providedNonce: string): boolean => {
const cachedNonce = nonceCache.get<string>(nonceKey);

// Check if the nonce matches and is not expired
if (providedNonce === nonce && Date.now() < expires) {
delete nonceStore[userId];
if (cachedNonce && cachedNonce === providedNonce) {
nonceCache.del(nonceKey); // Delete nonce after successful validation
return true;
}

Expand Down

0 comments on commit a52fec3

Please sign in to comment.