Skip to content

Commit

Permalink
Avoid on duplicate key update call in setUserData (#1426)
Browse files Browse the repository at this point in the history
  • Loading branch information
cd-rite authored Nov 12, 2024
1 parent 90e8e2b commit e18176d
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 40 deletions.
13 changes: 0 additions & 13 deletions api/source/controllers/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,3 @@ module.exports.updateUser = async function updateUser (req, res, next) {
next(err)
}
}

/* c8 ignore start */
module.exports.setUserData = async function setUserData (username, fields) {
try {
await UserService.setUserData(username, fields)
return await UserService.getUserByUsername(username)
}
catch (e) {
next(err)

}
}
/* c8 ignore end */
32 changes: 6 additions & 26 deletions api/source/service/UserService.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,34 +319,14 @@ exports.updateUser = async function( userId, body, projection, elevate, userObje
}
}

exports.setLastAccess = async function (userId, timestamp) {
let sqlUpdate = `UPDATE user_data SET lastAccess = ? where userId = ?`
await dbUtils.pool.execute(sqlUpdate, [timestamp, userId])
return true
}

exports.setUserData = async function (userObject, fields) {
let insertColumns = ['username']
// Apparently the standard MySQL practice to ensure insertId is valid even on non-updating updates
// See: https://chrisguitarguy.com/2020/01/26/mysql-last-insert-id-on-duplicate-key-update/
let updateColumns = ['userId = LAST_INSERT_ID(userId)']
// let updateColumns = []
let binds = [userObject.username]
if (fields.lastAccess) {
insertColumns.push('lastAccess')
updateColumns.push('lastAccess = VALUES(lastAccess)')
binds.push(fields.lastAccess)
if (userObject.userId) {
await dbUtils.pool.query(`UPDATE user_data SET ? WHERE userId = ?`, [fields, userObject.userId])
return userObject.userId
}
if (fields.lastClaims) {
insertColumns.push('lastClaims')
updateColumns.push('lastClaims = VALUES(lastClaims)')
binds.push(JSON.stringify(fields.lastClaims))
else {
const [result] = await dbUtils.pool.query(`INSERT INTO user_data SET ?`, [{username: userObject.username, ...fields}])
return result.insertId
}
let sqlUpsert = `INSERT INTO user_data (
${insertColumns.join(',\n')}
) VALUES ? ON DUPLICATE KEY UPDATE
${updateColumns.join(',\n')}`
let [result] = await dbUtils.pool.query(sqlUpsert, [[binds]])
return result.insertId
}

2 changes: 1 addition & 1 deletion api/source/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const verifyRequest = async function (req, requiredScopes, securityDefinition) {
refreshFields.lastAccess = now
}
if (!response?.statistics?.lastClaims || decoded[config.oauth.claims.assertion] !== response?.statistics?.lastClaims?.[config.oauth.claims.assertion]) {
refreshFields.lastClaims = decoded
refreshFields.lastClaims = JSON.stringify(decoded)
}
if (req.userObject.username && (refreshFields.lastAccess || refreshFields.lastClaims)) {
const userId = await User.setUserData(req.userObject, refreshFields)
Expand Down

0 comments on commit e18176d

Please sign in to comment.