script to export users to auth0

This commit is contained in:
Emi Matchu 2020-09-02 03:49:58 -07:00
parent 3c3d18d371
commit 6982f00729
4 changed files with 127 additions and 5 deletions

View file

@ -42,7 +42,8 @@
"mysql": "mysql --host=impress.openneo.net --user=$(dotenv -p IMPRESS_MYSQL_USER) --password=$(dotenv -p IMPRESS_MYSQL_PASSWORD) --database=openneo_impress", "mysql": "mysql --host=impress.openneo.net --user=$(dotenv -p IMPRESS_MYSQL_USER) --password=$(dotenv -p IMPRESS_MYSQL_PASSWORD) --database=openneo_impress",
"mysql-admin": "mysql --host=impress.openneo.net --user=matchu --password --database=openneo_impress", "mysql-admin": "mysql --host=impress.openneo.net --user=matchu --password --database=openneo_impress",
"build-cached-data": "node -r dotenv/config scripts/build-cached-data.js", "build-cached-data": "node -r dotenv/config scripts/build-cached-data.js",
"cache-asset-manifests": "node -r dotenv/config scripts/cache-asset-manifests.js" "cache-asset-manifests": "node -r dotenv/config scripts/cache-asset-manifests.js",
"build-user-export-for-auth0": "node -r dotenv/config scripts/build-user-export-for-auth0.js"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": "react-app"
@ -65,6 +66,7 @@
"customize-cra-react-refresh": "^1.1.0", "customize-cra-react-refresh": "^1.1.0",
"dotenv-cli": "^3.1.0", "dotenv-cli": "^3.1.0",
"es6-promise-pool": "^2.5.0", "es6-promise-pool": "^2.5.0",
"inquirer": "^7.3.3",
"prettier": "^2.0.5", "prettier": "^2.0.5",
"react-app-rewired": "^2.1.6" "react-app-rewired": "^2.1.6"
} }

View file

@ -0,0 +1,78 @@
// This generates a JSON file to export our users into Auth0.
//
// This sorta creates a second copy of everyone's account, copied onto Auth0.
// We should be thoughtful about how we do the actual migration process!
//
// For now, we can run this whenever we want to make it _possible_ to log in
// with Auth0, even if things will be potentially out of sync, because traffic
// to Impress 2020 is just testers now anyway!
const fs = require("fs").promises;
const path = require("path");
const os = require("os");
const inquirer = require("inquirer");
const connectToDb = require("../src/server/db");
const { normalizeRow } = require("../src/server/util");
async function main() {
const { user, password, outputPath } = await inquirer.prompt([
{ name: "user", message: "MySQL admin user:" },
{ name: "password", type: "password" },
{
name: "outputPath",
message: "Output path:",
default: path.join(
os.homedir(),
"Downloads/openneo-users-for-auth0.json"
),
},
]);
const db = await connectToDb({ user, password });
let users;
try {
const [rows] = await db.query(
`SELECT id, name, email, encrypted_password, password_salt
FROM openneo_id.users ORDER BY id`
);
users = rows.map(normalizeRow);
} finally {
db.close();
}
const usersInAuth0Format = users.map((user) => ({
user_id: user.id,
username: user.name,
email: user.email,
custom_password_hash: {
algorithm: "hmac",
hash: {
value: user.encryptedPassword,
encoding: "hex",
digest: "sha256",
key: {
encoding: "utf8",
value: user.passwordSalt,
},
},
},
}));
for (let i = 0; i < users.length; i += 1000) {
const batchInAuth0Format = usersInAuth0Format.slice(i, i + 1000);
const batchOutputPath = outputPath.replace(/\.json$/, `-${i}.json`);
const jsonOutput = JSON.stringify(batchInAuth0Format);
await fs.writeFile(batchOutputPath, jsonOutput);
console.log(
`📚 Wrote ${batchInAuth0Format.length} users to ${batchOutputPath}`
);
}
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.then(() => process.exit());

View file

@ -2,7 +2,10 @@ const mysql = require("mysql2");
let globalDb; let globalDb;
async function connectToDb() { async function connectToDb({
user = process.env["IMPRESS_MYSQL_USER"],
password = process.env["IMPRESS_MYSQL_PASSWORD"],
} = {}) {
if (globalDb) { if (globalDb) {
return globalDb; return globalDb;
} }
@ -10,8 +13,8 @@ async function connectToDb() {
globalDb = mysql globalDb = mysql
.createConnection({ .createConnection({
host: "impress.openneo.net", host: "impress.openneo.net",
user: process.env["IMPRESS_MYSQL_USER"], user,
password: process.env["IMPRESS_MYSQL_PASSWORD"], password,
database: "openneo_impress", database: "openneo_impress",
}) })
// We upgrade to promises here, instead of using the mysql2/promise import, // We upgrade to promises here, instead of using the mysql2/promise import,

View file

@ -4360,6 +4360,14 @@ chalk@^3.0.0:
ansi-styles "^4.1.0" ansi-styles "^4.1.0"
supports-color "^7.1.0" supports-color "^7.1.0"
chalk@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chardet@^0.7.0: chardet@^0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@ -4463,6 +4471,11 @@ cli-width@^2.0.0:
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
cli-width@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
cliui@^4.0.0: cliui@^4.0.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
@ -7332,6 +7345,25 @@ inquirer@^7.0.0:
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
through "^2.3.6" through "^2.3.6"
inquirer@^7.3.3:
version "7.3.3"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003"
integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==
dependencies:
ansi-escapes "^4.2.1"
chalk "^4.1.0"
cli-cursor "^3.1.0"
cli-width "^3.0.0"
external-editor "^3.0.3"
figures "^3.0.0"
lodash "^4.17.19"
mute-stream "0.0.8"
run-async "^2.4.0"
rxjs "^6.6.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
through "^2.3.6"
internal-ip@^4.3.0: internal-ip@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907"
@ -8608,7 +8640,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
lodash@>=4.17.19: lodash@>=4.17.19, lodash@^4.17.19:
version "4.17.20" version "4.17.20"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
@ -11580,6 +11612,13 @@ rxjs@^6.5.3:
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
rxjs@^6.6.0:
version "6.6.2"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2"
integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==
dependencies:
tslib "^1.9.0"
safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"