-
Notifications
You must be signed in to change notification settings - Fork 212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(apple): Add apple user migrations script #15406
Conversation
this.appleUserInfo = res.data; | ||
return res.data; | ||
} catch (err) { | ||
this.setFailure(err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a look at the retry later ability and kinda went down a rabbit hole. Instead, we mark the user as failed and can reattempt later.
|
||
async createLinkedAccount(accountRecord, sub) { | ||
// If the user already has a linked account, delete it and create a new one. | ||
await this.db.deleteLinkedAccount(accountRecord.uid, APPLE_PROVIDER); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There shouldn't be any harm in deleting a linked third party auth account. The feature is not broadcasted so no real users should have this set.
|
||
it('should exchange identifiers correctly and update user', async function() { | ||
const stub = sandbox.stub(axios, 'post').resolves({ data: { sub: 'sub', email: 'email@example.com', is_private_email: true } }); | ||
const data = await user.exchangeIdentifiers('accessToken'); |
Check failure
Code scanning / CodeQL
Hard-coded credentials
it('should transfer user correctly', async function() { | ||
sandbox.stub(user, 'exchangeIdentifiers').resolves(); | ||
sandbox.stub(user, 'createUpdateFxAUser').resolves(); | ||
await user.transferUser('accessToken'); |
Check failure
Code scanning / CodeQL
Hard-coded credentials
.option('-d, --delimiter [delimiter]', 'Delimiter for input file', ',') | ||
.option('-o, --output <filename>', 'Output filename to save results to') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Does the program.delimiter
and program.output
get used?
return input.split(/\n/).map((s, index) => { | ||
if (index === 0) return; | ||
|
||
const delimiter = program.delimiter || ','; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the only other instance of program
i found in this file:
fxa/packages/fxa-auth-server/scripts/apple-transfer-users/apple-transfer-users.js
Line 15 in ea9bb53
const program = require('commander'); |
Should this be using the unused(?) delimiter
from packages/fxa-auth-server/scripts/apple-transfer-users.js#L7 above?
const err = (user.err && user.err.message) || ''; | ||
return `${transferSub},${uid},${fxaEmail},${appleEmail},${success},${err}`; | ||
}).join('\n'); | ||
fs.writeFileSync(path.resolve(`${Date.now()}_output.csv`), output); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Should this accept an output filename?
packages/fxa-auth-server/scripts/apple-transfer-users.js#L20 specifies an output filename in the commander config, but I don't think it's used currently.
const transferSub = user.transferSub; | ||
const success = user.success; | ||
const err = (user.err && user.err.message) || ''; | ||
return `${transferSub},${uid},${fxaEmail},${appleEmail},${success},${err}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Would there be any potential issues if the ${err}
string had a comma (thus throwing off column counts, etc)?
const tokenRes = await axios.post(config.appleAuthConfig.tokenEndpoint, | ||
new URLSearchParams(tokenOptions).toString(), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: does this need a try..catch
in the unlikely event of a server/fetch error?
const migration = new ApplePocketFxAMigration(program.input); | ||
|
||
await migration.load(); | ||
await migration.printUsers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think printUsers()
is an async method:
fxa/packages/fxa-auth-server/scripts/apple-transfer-users/apple-transfer-users.js
Lines 176 to 178 in ea9bb53
printUsers() { | |
console.table(this.users); | |
} |
await migration.load(); | ||
await migration.printUsers(); | ||
await migration.transferUsers(); | ||
await migration.saveResults(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same w/ non-async saveResults()
:
fxa/packages/fxa-auth-server/scripts/apple-transfer-users/apple-transfer-users.js
Lines 180 to 181 in ea9bb53
saveResults() { | |
const output = this.users.map((user) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple nits. Would be good to address the comments in saveResults.
@@ -0,0 +1,259 @@ | |||
/* This Source Code Form is subject to the terms of the Mozilla Public |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Might be nice to just call this /transfer-users/apple.js. That way if there are other types of user transfers in the future, we can just add more scripts here.
AUTH_FIRESTORE_EMULATOR_HOST: 'localhost:9090', | ||
}, | ||
}; | ||
const axios = require('axios'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Any reason to axios
instead of fetch
?
return res.data; | ||
} catch (err) { | ||
this.setFailure(err); | ||
if (err.response && err.response.status === 429) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we want to add a delay option, so we can throttle?
|
||
// Exchanges the Apple `transfer_sub` for the user's profile information and | ||
// moves the user to the new team. | ||
// Ref: https://developer.apple.com/documentation/sign_in_with_apple/bringing_new_apps_and_users_into_your_team#3559300 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
||
program | ||
.option('-d, --delimiter [delimiter]', 'Delimiter for input file', ',') | ||
.option('-o, --output <filename>', 'Output filename to save results to') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this have a default value?
const err = (user.err && user.err.message) || ''; | ||
return `${transferSub},${uid},${fxaEmail},${appleEmail},${success},${err}`; | ||
}).join('\n'); | ||
fs.writeFileSync(path.resolve(`${Date.now()}_output.csv`), output); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be program.output
?
} | ||
|
||
saveResults() { | ||
const output = this.users.map((user) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a really big string. Perhaps write the file line by line?
Because
This pull request
Issue that this pull request solves
Closes: https://mozilla-hub.atlassian.net/browse/FXA-7490
Checklist
Other information (Optional)
I need to find a better way to test this script. Since it is making network calls from another Node process, I can't use nock. I'm putting this up for initial review, it is still missing a few things