script to export users to auth0
This commit is contained in:
parent
3c3d18d371
commit
6982f00729
4 changed files with 127 additions and 5 deletions
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
78
scripts/build-user-export-for-auth0.js
Normal file
78
scripts/build-user-export-for-auth0.js
Normal 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());
|
|
@ -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,
|
||||||
|
|
41
yarn.lock
41
yarn.lock
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue