Skip to content

Instantly share code, notes, and snippets.

@alexstrat
Last active December 13, 2019 13:12
Show Gist options
  • Save alexstrat/c0394709a4f5a46772c4be2ff1bb885f to your computer and use it in GitHub Desktop.
Save alexstrat/c0394709a4f5a46772c4be2ff1bb885f to your computer and use it in GitHub Desktop.
diff --git a/cli/migrate-user-from-auth0-to-firebase.ts b/cli/migrate-user-from-auth0-to-firebase.ts
new file mode 100644
index 0000000..2daa70e
--- /dev/null
+++ b/cli/migrate-user-from-auth0-to-firebase.ts
@@ -0,0 +1,72 @@
+import { ArgumentParser } from 'argparse';
+import { hashSync } from 'bcrypt';
+import { initFirebase } from '../src/authentication/firebase/helpers';
+import * as firebaseAdmin from 'firebase-admin';
+import { getUserListByIds as getAuth0UserListByIds} from '../src/users/auth0/helpers';
+import { getUserListByIds as getFirebaseUserListByIds} from '../src/users/firebase/helpers';
+import { User } from 'auth0';
+
+initFirebase();
+
+// usage
+// npx ts-node --transpile-only cli/migrate-user-from-auth0-to-firebase.ts "auth0|5df368b0ea47a40f0858612c" -P "Station123"
+const parser = new ArgumentParser({
+ addHelp: true,
+ description: 'Migrate 1 user from Auth0 to Firebase',
+});
+
+parser.addArgument(['userId']);
+parser.addArgument(['-P', '--password']);
+
+const args = parser.parseArgs();
+
+const getProviderFromIdentity = (auth0user: User) => (identity: any) => {
+ return {
+ displayName: auth0user.name,
+ email: auth0user.email,
+ photoURL: auth0user.picture,
+ providerId: identity.provider === 'google-oauth2' ? 'google.com' : 'password',
+ uid: identity.user_id,
+ };
+};
+
+const formatFirebaseCreateUser = (auth0user: User) => {
+ return {
+ disabled: false,
+ uid: auth0user.user_id,
+ displayName: auth0user.name, // TBD
+ email: auth0user.email,
+ emailVerified: Boolean(auth0user.email_verified),
+ metadata: {
+ creationTime: auth0user.created_at,
+ },
+ photoURL: auth0user.picture,
+ providerData: auth0user.identities.map(getProviderFromIdentity(auth0user)),
+ };
+};
+
+async function migrateUser(userId: string, password?: string) {
+ console.log(`Migration ${userId}`);
+ const [auth0user] = await getAuth0UserListByIds([userId]);
+ if (!auth0user) throw new Error(`User ${userId} not found`);
+
+ const [firebaseUser] = await getFirebaseUserListByIds([userId]);
+ // @ts-ignore
+ if (firebaseUser && firebaseUser.user_id) throw new Error(`User ${userId} already exists`);
+
+ const userToImport = formatFirebaseCreateUser(auth0user);
+
+ if (password) {
+ // @ts-ignore
+ userToImport.passwordHash = Buffer.from(hashSync(password, 10));
+ }
+
+ console.log(userToImport);
+
+ // @ts-ignore
+ await firebaseAdmin.auth().importUsers([userToImport], { hash: { algorithm: 'BCRYPT' } });
+}
+
+migrateUser(args.userId, args.password)
+ .then(() => console.log('success'))
+ .catch((e) => console.log('Failed', e));
diff --git a/package.json b/package.json
index b2a45de..fc5b7e4 100644
--- a/package.json
+++ b/package.json
@@ -65,6 +65,7 @@
"apollo-server-koa": "^2.9.0",
"apollo-server-plugin-base": "^0.6.1",
"auth0": "^2.9.1",
+ "bcrypt": "^3.0.7",
"bluebird": "^3.5.3",
"body-parser": "^1.18.3",
"config": "^1.29.0",
@@ -124,6 +125,7 @@
"@graphql-codegen/typescript-resolvers": "^1.8.3",
"@types/argparse": "^1.0.33",
"@types/auth0": "^2.7.1",
+ "@types/bcrypt": "^3.0.0",
"@types/bluebird": "^3.5.25",
"@types/body-parser": "^1.17.0",
"@types/bugsnag": "^2.5.28",
diff --git a/yarn.lock b/yarn.lock
index 15f1642..fe17e62 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1540,6 +1540,11 @@
dependencies:
"@babel/types" "^7.3.0"
+"@types/bcrypt@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-3.0.0.tgz#851489a9065a067cb7f3c9cbe4ce9bed8bba0876"
+ integrity sha512-nohgNyv+1ViVcubKBh0+XiNJ3dO8nYu///9aJ4cgSqv70gBL+94SNy/iC2NLzKPT2Zt/QavrOkBVbZRLZmw6NQ==
+
"@types/bluebird@*":
version "3.5.29"
resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.29.tgz#7cd933c902c4fc83046517a1bef973886d00bdb6"
@@ -2944,6 +2949,14 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
+bcrypt@^3.0.7:
+ version "3.0.7"
+ resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-3.0.7.tgz#1187d29df2e1cde44268152b13e3d4a655a7c7de"
+ integrity sha512-K5UglF9VQvBMHl/1elNyyFvAfOY9Bj+rpKrCSR9sFwcW8FywAYJSRwTURNej5TaAK2TEJkcJ6r6lh1YPmspx5Q==
+ dependencies:
+ nan "2.14.0"
+ node-pre-gyp "0.13.0"
+
[email protected]:
version "2.4.3"
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
@@ -8783,7 +8796,7 @@ mz@^2.7.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
-nan@^2.12.1, nan@^2.13.2:
[email protected], nan@^2.12.1, nan@^2.13.2:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
@@ -8927,6 +8940,22 @@ node-notifier@^5.4.2:
shellwords "^0.1.1"
which "^1.3.0"
[email protected]:
+ version "0.13.0"
+ resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42"
+ integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==
+ dependencies:
+ detect-libc "^1.0.2"
+ mkdirp "^0.5.1"
+ needle "^2.2.1"
+ nopt "^4.0.1"
+ npm-packlist "^1.1.6"
+ npmlog "^4.0.2"
+ rc "^1.2.7"
+ rimraf "^2.6.1"
+ semver "^5.3.0"
+ tar "^4"
+
node-pre-gyp@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment