Skip to content
This repository was archived by the owner on Apr 3, 2019. It is now read-only.

Commit 3c96a63

Browse files
committed
fix(mysql): Set strict mode on all new db migrations.
We've stored enforcing strict-mode on all connections to MySQL from the app at runtime. However, stored procedures remember the sql_mode that was in effect at the time they were created, and we create our stored procedures through an out-of-band connection that doesn't force strict mode. This change adds an explicit "enable strict mode" preamble to new migrations, and re-creates on of the existing stored procedures to make use of it. Once we're confident this will work on OK in practice, we'll need to re-create all stored procedures that might have been created without strict mode.
1 parent c94fe0b commit 3c96a63

File tree

5 files changed

+101
-3
lines changed

5 files changed

+101
-3
lines changed

lib/db/mysql.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ module.exports = function (log, error) {
203203

204204
// Insert : accounts
205205
// Values : uid = $1, normalizedEmail = $2, email = $3, emailCode = $4, emailVerified = $5, kA = $6, wrapWrapKb = $7, authSalt = $8, verifierVersion = $9, verifyHash = $10, verifierSetAt = $11, createdAt = $12, locale = $13
206-
var CREATE_ACCOUNT = 'CALL createAccount_7(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
206+
var CREATE_ACCOUNT = 'CALL createAccount_8(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
207207

208208
MySql.prototype.createAccount = function (uid, data) {
209209
return this.write(

lib/db/patch.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
// The expected patch level of the database. Update if you add a new
66
// patch in the ./schema/ directory.
7-
module.exports.level = 80
7+
module.exports.level = 81

lib/db/schema/patch-080-081.sql

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
SET SESSION sql_mode = CONCAT(@@sql_mode, ',STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION');
2+
SET NAMES utf8mb4 COLLATE utf8mb4_bin;
3+
4+
CREATE PROCEDURE `createAccount_8`(
5+
IN `inUid` BINARY(16) ,
6+
IN `inNormalizedEmail` VARCHAR(255),
7+
IN `inEmail` VARCHAR(255),
8+
IN `inEmailCode` BINARY(16),
9+
IN `inEmailVerified` TINYINT(1),
10+
IN `inKA` BINARY(32),
11+
IN `inWrapWrapKb` BINARY(32),
12+
IN `inAuthSalt` BINARY(32),
13+
IN `inVerifierVersion` TINYINT UNSIGNED,
14+
IN `inVerifyHash` BINARY(32),
15+
IN `inVerifierSetAt` BIGINT UNSIGNED,
16+
IN `inCreatedAt` BIGINT UNSIGNED,
17+
IN `inLocale` VARCHAR(255)
18+
)
19+
BEGIN
20+
DECLARE EXIT HANDLER FOR SQLEXCEPTION
21+
BEGIN
22+
ROLLBACK;
23+
RESIGNAL;
24+
END;
25+
26+
START TRANSACTION;
27+
28+
-- Check to see if the normalizedEmail exists in the emails table before creating a new user
29+
-- with this email.
30+
SET @emailExists = 0;
31+
SELECT COUNT(*) INTO @emailExists FROM emails WHERE normalizedEmail = inNormalizedEmail;
32+
IF @emailExists > 0 THEN
33+
SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO = 1062, MESSAGE_TEXT = 'Unable to create user, email used belongs to another user.';
34+
END IF;
35+
36+
INSERT INTO accounts(
37+
uid,
38+
normalizedEmail,
39+
email,
40+
emailCode,
41+
emailVerified,
42+
kA,
43+
wrapWrapKb,
44+
authSalt,
45+
verifierVersion,
46+
verifyHash,
47+
verifierSetAt,
48+
createdAt,
49+
locale
50+
)
51+
VALUES(
52+
inUid,
53+
LOWER(inNormalizedEmail),
54+
inEmail,
55+
inEmailCode,
56+
inEmailVerified,
57+
inKA,
58+
inWrapWrapKb,
59+
inAuthSalt,
60+
inVerifierVersion,
61+
inVerifyHash,
62+
inVerifierSetAt,
63+
inCreatedAt,
64+
inLocale
65+
);
66+
67+
INSERT INTO emails(
68+
normalizedEmail,
69+
email,
70+
uid,
71+
emailCode,
72+
isVerified,
73+
isPrimary,
74+
createdAt
75+
)
76+
VALUES(
77+
LOWER(inNormalizedEmail),
78+
inEmail,
79+
inUid,
80+
inEmailCode,
81+
inEmailVerified,
82+
true,
83+
inCreatedAt
84+
);
85+
86+
COMMIT;
87+
END;
88+
89+
UPDATE dbMetadata SET value = '81' WHERE name = 'schema-patch-level';

lib/db/schema/patch-081-080.sql

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- SET SESSION sql_mode = CONCAT(@@sql_mode, ',STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION');
2+
-- SET NAMES utf8mb4 COLLATE utf8mb4_bin;
3+
4+
-- DROP PROCEDURE createAccount_8;
5+
6+
-- UPDATE dbMetadata SET value = '80' WHERE name = 'schema-patch-level';
7+

scripts/migration.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ fi
3232

3333
printf "Generating migration boilerplate for patch level $NEW_LEVEL..."
3434

35-
echo "SET NAMES utf8mb4 COLLATE utf8mb4_bin;\n" > "$FWD_SCHEMA"
35+
echo "SET SESSION sql_mode = CONCAT(@@sql_mode, ',STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION');" > "$FWD_SCHEMA"
36+
echo "SET NAMES utf8mb4 COLLATE utf8mb4_bin;\n" >> "$FWD_SCHEMA"
3637
echo "-- TODO: Implement your forward migration here\n" >> "$FWD_SCHEMA"
3738
echo "UPDATE dbMetadata SET value = '$NEW_LEVEL' WHERE name = 'schema-patch-level';\n" >> "$FWD_SCHEMA"
3839

3940
echo '-- -- TODO: Implement your *commented-out* reverse migration here\n' > "$REV_SCHEMA"
41+
echo "-- SET SESSION sql_mode = CONCAT(@@sql_mode, ',STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION');" > "$REV_SCHEMA"
4042
echo "-- SET NAMES utf8mb4 COLLATE utf8mb4_bin;\n" >> "$REV_SCHEMA"
4143
echo "-- UPDATE dbMetadata SET value = '$PREV_LEVEL' WHERE name = 'schema-patch-level';\n" >> "$REV_SCHEMA"
4244

0 commit comments

Comments
 (0)