Skip to content

Commit

Permalink
refactor: optimize auth command and related libraries separation; gen…
Browse files Browse the repository at this point in the history
…eralize core lib methods
  • Loading branch information
0xjei committed Jan 16, 2023
1 parent 144f702 commit 7bc462c
Show file tree
Hide file tree
Showing 23 changed files with 485 additions and 516 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"rules": {
"no-underscore-dangle": "off",
"import/no-extraneous-dependencies": "off",
"import/prefer-default-export": "warn",
"consistent-return": "warn",
"no-bitwise": "off",
"no-await-in-loop": "off",
"no-restricted-syntax": "off",
Expand Down
59 changes: 0 additions & 59 deletions packages/actions/src/core/auth/index.ts

This file was deleted.

63 changes: 0 additions & 63 deletions packages/actions/src/core/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,5 @@
import open from "open"
// import clipboard from "clipboardy" // TODO: need a substitute.
import { Verification } from "@octokit/auth-oauth-device/dist-types/types"
import { OAuthCredential, GithubAuthProvider } from "firebase/auth"
import { firstZkeyIndex } from "../../helpers/constants"

/**
* @dev TODO: needs refactoring.
* Custom countdown which throws an error when expires.
* @param durationInSeconds <number> - the amount of time to be counted expressed in seconds.
* @param intervalInSeconds <number> - the amount of time that must elapse between updates (default 1s === 1ms).
*/
const createExpirationCountdown = (durationInSeconds: number, intervalInSeconds = 1000) => {
let seconds = durationInSeconds <= 60 ? durationInSeconds : 60

setInterval(() => {
try {
if (durationInSeconds !== 0) {
// Update times.
durationInSeconds -= intervalInSeconds
seconds -= intervalInSeconds

if (seconds % 60 === 0) seconds = 0

process.stdout.write(`Expires in 00:${Math.floor(durationInSeconds / 60)}:${seconds}\r`)
} else console.log(`Expired`)
} catch (err: any) {
// Workaround to the \r.
process.stdout.write(`\n\n`)
console.log(`Expired`)
}
}, intervalInSeconds * 1000)
}

/**
* Callback to manage the data requested for Github OAuth2.0 device flow.
* @param verification <Verification> - the data from Github OAuth2.0 device flow.
*/
export const onVerification = async (verification: Verification): Promise<void> => {
// Automatically open the page (# Step 2).
await open(verification.verification_uri)

// TODO: need a substitute for `clipboardy` package.
// Copy code to clipboard.
// clipboard.writeSync(verification.user_code)
// clipboard.readSync()

// Display data.
// TODO. custom theme is missing.
console.log(
`Visit ${verification.verification_uri} on this device to authenticate\nYour auth code: ${verification.user_code}`
)

// Countdown for time expiration.
createExpirationCountdown(verification.expires_in, 1)
}

/**
* Exchange the Github OAuth 2.0 token for a Firebase credential.
* @param token <string> - the Github OAuth 2.0 token to be exchanged.
* @returns <OAuthCredential> - the Firebase OAuth credential object.
*/
export const exchangeGithubTokenForFirebaseCredentials = (token: string): OAuthCredential =>
GithubAuthProvider.credential(token)

/**
* Get the powers from pot file name
* @dev the pot files must follow these convention (i_am_a_pot_file_09.ptau) where the numbers before '.ptau' are the powers.
Expand Down
80 changes: 80 additions & 0 deletions packages/actions/src/helpers/firebase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { FirebaseApp, FirebaseOptions, initializeApp } from "firebase/app" // ref https://firebase.google.com/docs/web/setup#access-firebase.
import { User, getAuth, signInWithCredential, initializeAuth, OAuthCredential } from "firebase/auth"
import { Firestore, getFirestore } from "firebase/firestore"
import { Functions, getFunctions } from "firebase/functions"
import { FirebaseServices } from "../../types/index"

/**
* This method initialize a Firebase app if no other app has already been initialized.
* @param options <FirebaseOptions> - an object w/ every necessary Firebase option to init app.
* @returns <FirebaseApp> - the initialized Firebase app object.
*/
const initializeFirebaseApp = (options: FirebaseOptions): FirebaseApp => initializeApp(options)

/**
* This method returns the Firestore database instance associated to the given Firebase application.
* @param app <FirebaseApp> - the Firebase application.
* @returns <Firestore> - the Firebase Firestore associated to the application.
*/
const getFirestoreDatabase = (app: FirebaseApp): Firestore => getFirestore(app)

/**
* This method returns the Cloud Functions instance associated to the given Firebase application.
* @param app <FirebaseApp> - the Firebase application.
* @returns <Functions> - the Cloud Functions associated to the application.
*/
const getFirebaseFunctions = (app: FirebaseApp): Functions => getFunctions(app)

/**
* Return the core Firebase services instances (App, Database, Functions).
* @param apiKey <string> - the API key specified in the application config.
* @param authDomain <string> - the authDomain string specified in the application config.
* @param projectId <string> - the projectId specified in the application config.
* @param messagingSenderId <string> - the messagingSenderId specified in the application config.
* @param appId <string> - the appId specified in the application config.
* @returns <Promise<FirebaseServices>>
*/
export const initializeFirebaseCoreServices = async (
apiKey: string,
authDomain: string,
projectId: string,
messagingSenderId: string,
appId: string
): Promise<FirebaseServices> => {
const firebaseApp = initializeFirebaseApp({
apiKey,
authDomain,
projectId,
messagingSenderId,
appId
})
const firestoreDatabase = getFirestoreDatabase(firebaseApp)
const firebaseFunctions = getFirebaseFunctions(firebaseApp)

return {
firebaseApp,
firestoreDatabase,
firebaseFunctions
}
}

/**
* Sign in w/ OAuth 2.0 token.
* @param firebaseApp <FirebaseApp> - the configured instance of the Firebase App in use.
* @param credentials <OAuthCredential> - the OAuth credential generated from token exchange.
*/
export const signInToFirebaseWithCredentials = async (firebaseApp: FirebaseApp, credentials: OAuthCredential) =>
signInWithCredential(initializeAuth(firebaseApp), credentials)

/**
* Return the current authenticated user in the given Firebase Application.
* @param firebaseApp <FirebaseApp> - the configured instance of the Firebase App in use.
* @returns
*/
export const getCurrentFirebaseAuthUser = (firebaseApp: FirebaseApp): User => {
const user = getAuth(firebaseApp).currentUser

if (!user) throw new Error(`Authenticated user not found for current Firebase application`)

return user
}
10 changes: 5 additions & 5 deletions packages/actions/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
export {
getCurrentFirebaseAuthUser,
getNewOAuthTokenUsingGithubDeviceFlow,
signInToFirebaseWithGithubToken
} from "./core/auth/index"
export {
getOpenedCeremonies,
getCeremonyCircuits,
Expand Down Expand Up @@ -54,3 +49,8 @@ export {
writeLocalJsonFile,
downloadFileFromUrl
} from "./helpers/files"
export {
initializeFirebaseCoreServices,
signInToFirebaseWithCredentials,
getCurrentFirebaseAuthUser
} from "./helpers/firebase"
10 changes: 9 additions & 1 deletion packages/actions/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { DocumentReference, DocumentData } from "firebase/firestore"
import { FirebaseApp } from "firebase/app"
import { DocumentReference, DocumentData, Firestore } from "firebase/firestore"
import { Functions } from "firebase/functions"

/** Enumeratives */
export enum CeremonyState {
Expand Down Expand Up @@ -77,6 +79,12 @@ export const enum CeremonyCollectionField {
}

/** Types */
export type FirebaseServices = {
firebaseApp: FirebaseApp
firestoreDatabase: Firestore
firebaseFunctions: Functions
}

export type FirebaseDocumentInfo = {
id: string
ref: DocumentReference<DocumentData>
Expand Down
1 change: 1 addition & 0 deletions packages/phase2cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"boxen": "^7.0.0",
"chalk": "^5.1.2",
"clear": "^0.1.0",
"clipboardy": "^3.0.0",
"cli-progress": "^3.11.2",
"commander": "^9.4.1",
"conf": "^10.2.0",
Expand Down
Loading

0 comments on commit 7bc462c

Please sign in to comment.