Skip to content

Commit

Permalink
refactor: add github account id to handle to avoid possible duplicati…
Browse files Browse the repository at this point in the history
…on of contributors identifiers
  • Loading branch information
0xjei committed Mar 10, 2023
1 parent 74dfc07 commit bff0567
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 35 deletions.
17 changes: 13 additions & 4 deletions packages/phase2cli/src/commands/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device"
import { Verification } from "@octokit/auth-oauth-device/dist-types/types"
import clipboard from "clipboardy"
import open from "open"
import { exchangeGithubTokenForCredentials, getGithubUserHandle, terminate } from "../lib/utils"
import {
exchangeGithubTokenForCredentials,
getGithubProviderUserId,
getUserHandleFromProviderUserId,
terminate
} from "../lib/utils"
import { bootstrapCommandExecutionAndServices, signInToFirebase } from "../lib/services"
import theme from "../lib/theme"
import { checkLocalAccessToken, getLocalAccessToken, setLocalAccessToken } from "../lib/localConfigs"
Expand Down Expand Up @@ -131,14 +136,18 @@ const auth = async () => {
await signInToFirebase(firebaseApp, credentials)

// Get Github handle.
const githubUserHandle = await getGithubUserHandle(String(token))
const providerUserId = await getGithubProviderUserId(String(token))

console.log(`${theme.symbols.success} You are authenticated as ${theme.text.bold(`@${githubUserHandle}`)}`)
console.log(
`${theme.symbols.success} You are authenticated as ${theme.text.bold(
`@${getUserHandleFromProviderUserId(providerUserId)}`
)}`
)
console.log(
`${theme.symbols.info} You are now able to compute contributions for zk-SNARK Phase2 Trusted Setup opened ceremonies`
)

terminate(githubUserHandle)
terminate(providerUserId)
}

export default auth
22 changes: 11 additions & 11 deletions packages/phase2cli/src/commands/contribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ const listenToCeremonyCircuitDocumentChanges = (
* @param participant <DocumentSnapshot<DocumentData>> - the Firestore document of the participant.
* @param ceremony <FirebaseDocumentInfo> - the Firestore document info about the selected ceremony.
* @param entropy <string> - the random value (aka toxic waste) entered by the participant for the contribution.
* @param userHandle <string> - the Github user handle associated to the authenticated account.
* @param providerUserId <string> - the unique provider user identifier associated to the authenticated account.
* @param accessToken <string> - the Github token generated through the Device Flow process.
*/
const listenToParticipantDocumentChanges = async (
Expand All @@ -638,7 +638,7 @@ const listenToParticipantDocumentChanges = async (
participant: DocumentSnapshot<DocumentData>,
ceremony: FirebaseDocumentInfo,
entropy: string,
userHandle: string,
providerUserId: string,
accessToken: string
) => {
// Listen to participant document changes.
Expand Down Expand Up @@ -799,7 +799,7 @@ const listenToParticipantDocumentChanges = async (
circuit,
participant,
entropy,
userHandle,
providerUserId,
false // not finalizing.
)
}
Expand Down Expand Up @@ -896,7 +896,7 @@ const listenToParticipantDocumentChanges = async (
true
)

terminate(userHandle)
terminate(providerUserId)
}

// Scenario (3.F).
Expand All @@ -922,7 +922,7 @@ const listenToParticipantDocumentChanges = async (
ceremony.id,
participant.id,
changedContributions,
userHandle,
providerUserId,
ceremony.data.title,
ceremony.data.prefix,
accessToken
Expand All @@ -936,7 +936,7 @@ const listenToParticipantDocumentChanges = async (
unsubscribe()

// Gracefully exit.
terminate(userHandle)
terminate(providerUserId)
}
}

Expand All @@ -949,7 +949,7 @@ const listenToParticipantDocumentChanges = async (
ceremony.id,
participant.id,
changedContributions,
userHandle,
providerUserId,
ceremony.data.title,
ceremony.data.prefix,
accessToken
Expand All @@ -963,7 +963,7 @@ const listenToParticipantDocumentChanges = async (
unsubscribe()

// Gracefully exit.
terminate(userHandle)
terminate(providerUserId)
}
}
})
Expand All @@ -980,7 +980,7 @@ const contribute = async () => {
const { firebaseApp, firebaseFunctions, firestoreDatabase } = await bootstrapCommandExecutionAndServices()

// Check for authentication.
const { user, handle, token } = await checkAuth(firebaseApp)
const { user, providerUserId, token } = await checkAuth(firebaseApp)

// Retrieve the opened ceremonies.
const ceremoniesOpenedForContributions = await getOpenedCeremonies(firestoreDatabase)
Expand Down Expand Up @@ -1051,7 +1051,7 @@ const contribute = async () => {
participant,
selectedCeremony,
entropy,
handle,
providerUserId,
token
)
} else {
Expand Down Expand Up @@ -1086,7 +1086,7 @@ const contribute = async () => {
}

// Exit gracefully.
terminate(handle)
terminate(providerUserId)
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/phase2cli/src/commands/finalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ const finalize = async () => {
const { firebaseApp, firebaseFunctions, firestoreDatabase } = await bootstrapCommandExecutionAndServices()

// Check for authentication.
const { user, handle, token: coordinatorAccessToken } = await checkAuth(firebaseApp)
const { user, providerUserId, token: coordinatorAccessToken } = await checkAuth(firebaseApp)

// Preserve command execution only for coordinators.
if (!(await isCoordinator(user))) showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true)
Expand Down Expand Up @@ -301,7 +301,7 @@ const finalize = async () => {
circuit,
participant,
beacon,
handle
providerUserId
)

process.stdout.write(`\n`)
Expand Down Expand Up @@ -332,7 +332,7 @@ const finalize = async () => {
selectedCeremony.id,
participant.id,
contributions,
handle,
providerUserId,
ceremonyName,
true
)
Expand Down Expand Up @@ -372,7 +372,7 @@ const finalize = async () => {
// Automatically open a webpage with the tweet.
await open(tweetUrl)

terminate(handle)
terminate(providerUserId)
}

export default finalize
4 changes: 2 additions & 2 deletions packages/phase2cli/src/commands/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ const setup = async () => {
const { firebaseApp, firebaseFunctions, firestoreDatabase } = await bootstrapCommandExecutionAndServices()

// Check for authentication.
const { user, handle } = await checkAuth(firebaseApp)
const { user, providerUserId } = await checkAuth(firebaseApp)

// Preserve command execution only for coordinators.
if (!(await isCoordinator(user))) showError(COMMAND_ERRORS.COMMAND_NOT_COORDINATOR, true)
Expand Down Expand Up @@ -700,7 +700,7 @@ const setup = async () => {
}. You will be able to find all the files and info respectively in the ceremony bucket and database document.`
)
}
terminate(handle)
terminate(providerUserId)
}

export default setup
2 changes: 1 addition & 1 deletion packages/phase2cli/src/lib/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const CORE_SERVICES_ERRORS = {
export const THIRD_PARTY_SERVICES_ERRORS = {
GITHUB_ACCOUNT_ASSOCIATION_REJECTED: `You have decided not to associate the CLI application with your Github account. This declination will not allow you to make a contribution to any ceremony. In case you made a mistake, you can always repeat the process and accept the association of your Github account with the CLI.`,
GITHUB_SERVER_TIMEDOUT: `Github's servers are experiencing downtime. Please, try once again later and make sure your Internet connection is stable.`,
GITHUB_GET_HANDLE_FAILED: `Something went wrong while retrieving your Github handle. Please, try once again later`,
GITHUB_GET_GITHUB_ACCOUNT_INFO: `Something went wrong while retrieving your Github account public information (handle and identifier). Please, try once again later`,
GITHUB_NOT_AUTHENTICATED: `You are unable to execute the command since you have not authorized this device with your Github account. Please, execute the auth command (\`phase2cli auth\`) and then re-run this command.`,
GITHUB_GIST_PUBLICATION_FAILED: `Unable to publish the public attestation as gist making the request using your authenticated Github account. Please, verify that you have allowed the 'gist' access permission during the authentication step.`
}
Expand Down
12 changes: 7 additions & 5 deletions packages/phase2cli/src/lib/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { FirebaseServices } from "@zkmpc/actions/src/types"
import { showError, CONFIG_ERRORS, CORE_SERVICES_ERRORS, THIRD_PARTY_SERVICES_ERRORS } from "./errors"
import theme from "./theme"
import { checkLocalAccessToken, deleteLocalAccessToken, getLocalAccessToken } from "./localConfigs"
import { exchangeGithubTokenForCredentials, getGithubUserHandle } from "./utils"
import { exchangeGithubTokenForCredentials, getGithubProviderUserId, getUserHandleFromProviderUserId } from "./utils"

/**
* Bootstrap services and configs is needed for a new command execution and related services.
Expand Down Expand Up @@ -131,15 +131,17 @@ export const checkAuth = async (firebaseApp: FirebaseApp): Promise<AuthUser> =>
// Get current authenticated user.
const user = getCurrentFirebaseAuthUser(firebaseApp)

// Get Github handle.
const githubUserHandle = await getGithubUserHandle(String(token))
// Get Github unique identifier (handle-id).
const providerUserId = await getGithubProviderUserId(String(token))

// Greet the user.
console.log(`Greetings, @${theme.text.bold(githubUserHandle)} ${theme.emojis.wave}\n`)
console.log(
`Greetings, @${theme.text.bold(getUserHandleFromProviderUserId(providerUserId))} ${theme.emojis.wave}\n`
)

return {
user,
token,
handle: githubUserHandle
providerUserId
}
}
26 changes: 20 additions & 6 deletions packages/phase2cli/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,35 @@ export const exchangeGithubTokenForCredentials = (githubToken: string): OAuthCre
GithubAuthProvider.credential(githubToken)

/**
* Get the Github handle associated to the account from which the token has been generated.
* Get the information associated to the account from which the token has been generated to
* create a custom unique identifier for the user.
* @notice the unique identifier has the following form 'handle-identifier'.
* @param githubToken <string> - the Github token.
* @returns <Promise<any>> - the Github handle of the user.
* @returns <Promise<any>> - the Github (provider) unique identifier associated to the user.
*/
export const getGithubUserHandle = async (githubToken: string): Promise<any> => {
export const getGithubProviderUserId = async (githubToken: string): Promise<any> => {
// Ask for user account public information through Github API.
const response = await request("GET https://api.github.com/user", {
headers: {
authorization: `token ${githubToken}`
}
})

if (response && response.status === 200) return response.data.login
if (response && response.status === 200) return `${response.data.login}-${response.data.id}`

showError(THIRD_PARTY_SERVICES_ERRORS.GITHUB_GET_HANDLE_FAILED, true)
showError(THIRD_PARTY_SERVICES_ERRORS.GITHUB_GET_GITHUB_ACCOUNT_INFO, true)
}

/**
* Return the Github handle from the provider user id.
* @notice the provider user identifier must have the following structure 'handle-id'.
* @param providerUserId <string> - the unique provider user identifier.
* @returns <string> - the third-party provider handle of the user.
*/
export const getUserHandleFromProviderUserId = (providerUserId: string): string => {
if (providerUserId.indexOf("-") === -1) showError(THIRD_PARTY_SERVICES_ERRORS.GITHUB_GET_GITHUB_ACCOUNT_INFO, true)

return providerUserId.split("-")[0]
}

/**
Expand Down Expand Up @@ -173,7 +187,7 @@ export const convertMillisToSeconds = (millis: number): number => Number((millis
* @params ghUsername <string> - the Github username of the user.
*/
export const terminate = async (ghUsername: string) => {
console.log(`\nSee you, ${theme.text.bold(`@${ghUsername}`)} ${theme.emojis.wave}`)
console.log(`\nSee you, ${theme.text.bold(`@${getUserHandleFromProviderUserId(ghUsername)}`)} ${theme.emojis.wave}`)

process.exit(0)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/phase2cli/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export enum ProgressBarType {
* @typedef {Object} AuthUser
* @property {FirebaseAuthUser} user - the instance of the Firebase authenticated user.
* @property {string} token - the access token.
* @property {string} handle - the user handle from the third party provider (e.g., Github handle).
* @property {string} providerUserId - the unique identifier of the user tied to its account from a third party provider (e.g., Github).
*/
export type AuthUser = {
user: FirebaseAuthUser
token: string
handle: string
providerUserId: string
}

/**
Expand Down

0 comments on commit bff0567

Please sign in to comment.