Skip to content

Commit b81e8f4

Browse files
committed
Asynchronous Handling Issue in API Key Hashing Middleware
Previously, next() was being called after hashing each API key, which caused multiple calls and issues. The new solution uses a pendingTasks counter to wait until all async operations are completed. This fix prevents Mongoose errors and premature next() calls, ensuring proper API key hashing.
1 parent 2f99876 commit b81e8f4

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

server/models/user.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,34 +116,45 @@ userSchema.pre('save', function checkPassword(next) {
116116
* API keys hash middleware
117117
*/
118118
userSchema.pre('save', function checkApiKey(next) {
119-
// eslint-disable-line consistent-return
120119
const user = this;
121120
if (!user.isModified('apiKeys')) {
122-
next();
123-
return;
121+
return next();
124122
}
123+
125124
let hasNew = false;
125+
let pendingTasks = 0;
126+
let nextCalled = false;
127+
128+
const done = (err) => {
129+
if (nextCalled) return;
130+
if (err) {
131+
nextCalled = true;
132+
return next(new Error(err)); // ✅ Pass Error object
133+
}
134+
if (--pendingTasks === 0) {
135+
nextCalled = true;
136+
return next();
137+
}
138+
};
139+
126140
user.apiKeys.forEach((k) => {
127141
if (k.isNew) {
128142
hasNew = true;
143+
pendingTasks++;
129144
bcrypt.genSalt(10, (err, salt) => {
130-
// eslint-disable-line consistent-return
131-
if (err) {
132-
next(err);
133-
return;
134-
}
145+
if (err) return done(err);
135146
bcrypt.hash(k.hashedKey, salt, (innerErr, hash) => {
136-
if (innerErr) {
137-
next(innerErr);
138-
return;
139-
}
147+
if (innerErr) return done(innerErr);
140148
k.hashedKey = hash;
141-
next();
149+
done();
142150
});
143151
});
144152
}
145153
});
146-
if (!hasNew) next();
154+
155+
if (!hasNew) {
156+
return next();
157+
}
147158
});
148159

149160
userSchema.virtual('id').get(function idToString() {

0 commit comments

Comments
 (0)