diff --git a/migrations/20200530194049-appPasswords-change-unique-constraint.js b/migrations/20200530194049-appPasswords-change-unique-constraint.js new file mode 100644 index 000000000..908332227 --- /dev/null +++ b/migrations/20200530194049-appPasswords-change-unique-constraint.js @@ -0,0 +1,17 @@ +'use strict'; + +var async = require('async'); + +exports.up = function(db, callback) { + + // http://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address + + async.series([ + db.runSql.bind(db, 'ALTER TABLE appPasswords DROP INDEX name'), + db.runSql.bind(db, 'ALTER TABLE appPasswords ADD CONSTRAINT appPasswords_name_userId_identifier UNIQUE (name, userId, identifier)'), + ], callback); +}; + +exports.down = function(db, callback) { + callback(); +}; diff --git a/migrations/schema.sql b/migrations/schema.sql index cb98d9c97..ddecda16e 100644 --- a/migrations/schema.sql +++ b/migrations/schema.sql @@ -219,7 +219,7 @@ CREATE TABLE IF NOT EXISTS notifications( message TEXT, acknowledged BOOLEAN DEFAULT false, creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - + UNIQUE KEY appPasswords_name_appId_identifier (name, userId, identifier), PRIMARY KEY (id) ); @@ -231,7 +231,7 @@ CREATE TABLE IF NOT EXISTS appPasswords( hashedPassword VARCHAR(1024) NOT NULL, creationTime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY(userId) REFERENCES users(id), - UNIQUE (name, userId), + PRIMARY KEY (id) ); diff --git a/src/userdb.js b/src/userdb.js index b65f094ad..949a499cc 100644 --- a/src/userdb.js +++ b/src/userdb.js @@ -304,6 +304,7 @@ function addAppPassword(id, appPassword, callback) { const args = [ id, appPassword.userId, appPassword.identifier, appPassword.name, appPassword.hashedPassword ]; database.query(query, args, function (error) { + if (error && error.code === 'ER_DUP_ENTRY' && error.message.indexOf('appPasswords_name_userId_identifier') !== -1) return callback(new BoxError(BoxError.ALREADY_EXISTS, 'name/app combination already exists')); if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null);