Skip to content
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

chore(merge) - staging to main #167

Merged
merged 5 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions .github/workflows/publish-dev-packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- dev

jobs:
npm-publish:
npm-publish-dev:
runs-on: ubuntu-22.04
environment: dev

Expand All @@ -20,28 +20,35 @@ jobs:
registry-url: "https://registry.npmjs.org"
cache: yarn

- name: Update package.json dependencies and names
run: |
# Enable recursive globbing
shopt -s globstar

# Update package.json dependencies
sed -i -e 's/"@p0tion\/actions": "[^"]*"/"@devtion\/actions": "latest"/g' ./packages/backend/package.json
sed -i -e 's/"@p0tion\/actions": "[^"]*"/"@devtion\/actions": "latest"/g' ./packages/phase2cli/package.json

# Update package names
sed -i -e 's/"name": "@p0tion\/phase2cli"/"name": "@devtion\/devcli"/g' ./packages/phase2cli/package.json
sed -i -e 's/"name": "@p0tion\/backend"/"name": "@devtion\/backend"/g' ./packages/backend/package.json
sed -i -e 's/"name": "@p0tion\/actions"/"name": "@devtion\/actions"/g' ./packages/actions/package.json

# Update string literals in TypeScript files
sed -i 's|p0tion/actions|devtion/actions|g' packages/**/*.ts

- name: Initialize Project
run: |
yarn install
yarn build
env:
NODE_OPTIONS: "--max_old_space_size=4096"
YARN_ENABLE_IMMUTABLE_INSTALLS: "false"

- name: Install lerna
run: |
npm install -g lerna@7.1.4

- name: Filling package.json dependencies with latest version
run: |
sed -i -e 's/"@p0tion\/actions": "\^1.0.5"/"@devtion\/actions": "latest"/g' ./packages/backend/package.json
sed -i -e 's/"@p0tion\/actions": "\^1.0.5"/"@devtion\/actions": "latest"/g' ./packages/phase2cli/package.json

- name: Modify package name
run: |
sed -i -e 's/"name": "@p0tion\/phase2cli"/"name": "@devtion\/devcli"/g' ./packages/phase2cli/package.json
sed -i -e 's/"name": "@p0tion\/backend"/"name": "@devtion\/backend"/g' ./packages/backend/package.json
sed -i -e 's/"name": "@p0tion\/actions"/"name": "@devtion\/actions"/g' ./packages/actions/package.json

- name: Publish packages
run: |
# Prevent `git commit error` when running `lerna version`
Expand Down
28 changes: 18 additions & 10 deletions .github/workflows/publish-staging-packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ on:
- staging

jobs:
npm-publish:
npm-publish-staging:
runs-on: ubuntu-22.04
environment: staging

steps:
- uses: actions/checkout@v3
Expand All @@ -19,28 +20,35 @@ jobs:
registry-url: "https://registry.npmjs.org"
cache: yarn

- name: Filling package.json dependencies with latest version
- name: Update package.json dependencies and names
run: |
sed -i -e 's/"@p0tion\/actions": "\^1.0.5"/"@stagtion\/actions": "latest"/g' ./packages/backend/package.json
sed -i -e 's/"@p0tion\/actions": "\^1.0.5"/"@stagtion\/actions": "latest"/g' ./packages/phase2cli/package.json
# Enable recursive globbing
shopt -s globstar

# Update package.json dependencies
sed -i -e 's/"@p0tion\/actions": "[^"]*"/"@stagtion\/actions": "latest"/g' ./packages/backend/package.json
sed -i -e 's/"@p0tion\/actions": "[^"]*"/"@stagtion\/actions": "latest"/g' ./packages/phase2cli/package.json

# Update package names
sed -i -e 's/"name": "@p0tion\/phase2cli"/"name": "@stagtion\/stagcli"/g' ./packages/phase2cli/package.json
sed -i -e 's/"name": "@p0tion\/backend"/"name": "@stagtion\/backend"/g' ./packages/backend/package.json
sed -i -e 's/"name": "@p0tion\/actions"/"name": "@stagtion\/actions"/g' ./packages/actions/package.json

# Update string literals in TypeScript files
sed -i 's|p0tion/actions|stagtion/actions|g' packages/**/*.ts

- name: Initialize Project
run: |
yarn install
yarn build
env:
NODE_OPTIONS: "--max_old_space_size=4096"
YARN_ENABLE_IMMUTABLE_INSTALLS: "false"

- name: Install lerna
run: |
npm install -g lerna@7.1.4

- name: Modify package name
run: |
sed -i -e 's/"name": "@p0tion\/phase2cli"/"name": "@stagtion\/stagcli"/g' ./packages/phase2cli/package.json
sed -i -e 's/"name": "@p0tion\/backend"/"name": "@stagtion\/backend"/g' ./packages/backend/package.json
sed -i -e 's/"name": "@p0tion\/actions"/"name": "@stagtion\/actions"/g' ./packages/actions/package.json

- name: Publish packages
run: |
# Prevent `git commit error` when running `lerna version`
Expand Down
4 changes: 0 additions & 4 deletions packages/actions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@
"firebase": "^9.21.0",
"firebase-admin": "^11.8.0",
"googleapis": "^118.0.0",
"puppeteer": "^20.1.2",
"puppeteer-extra": "^3.3.6",
"puppeteer-extra-plugin-anonymize-ua": "^2.4.6",
"puppeteer-extra-plugin-stealth": "^2.11.2",
"rimraf": "^5.0.0",
"rollup": "^3.21.6",
"snarkjs": "^0.6.11",
Expand Down
46 changes: 19 additions & 27 deletions packages/actions/src/helpers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Firestore } from "firebase/firestore"
import fs, { ReadPosition } from "fs"
import fs, { ReadPosition, createWriteStream } from "fs"
import { utils as ffUtils } from "ffjavascript"
import winston, { Logger } from "winston"
import { S3Client, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3"
import fetch from "@adobe/node-fetch-retry"
import {
CircuitMetadata,
Contribution,
Expand All @@ -29,7 +29,7 @@ import {
getZkeyStorageFilePath
} from "./storage"
import { blake512FromPath } from "./crypto"
import { Readable, pipeline } from "stream"
import { pipeline } from "stream"
import { promisify } from "util"

/**
Expand Down Expand Up @@ -93,37 +93,27 @@ export const parseCeremonyFile = async (path: string, cleanup: boolean = false):
// where we storing the wasm downloaded
const localWasmPath = `./${circuitData.name}.wasm`

// check that the artifacts exist in S3
// we don't need any privileges to download this
// just the correct region
const s3 = new S3Client({
region: artifacts.region,
credentials: undefined
})

// download the r1cs to extract the metadata
const command = new GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.r1csStoragePath })
const response = await s3.send(command)
const streamPipeline = promisify(pipeline)

if (response.$metadata.httpStatusCode !== 200)
// Make the call.
const responseR1CS = await fetch(artifacts.r1csStoragePath)

// Handle errors.
if (!responseR1CS.ok && responseR1CS.status !== 200)
throw new Error(`There was an error while trying to download the r1cs file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`)

if (response.Body instanceof Readable)
await streamPipeline(response.Body, fs.createWriteStream(localR1csPath))
await streamPipeline(responseR1CS.body!, createWriteStream(localR1csPath))
// Write the file locally

// extract the metadata from the r1cs
const metadata = getR1CSInfo(localR1csPath)

// download wasm too to ensure it's available
const wasmCommand = new GetObjectCommand({ Bucket: artifacts.bucket, Key: artifacts.wasmStoragePath })
const wasmResponse = await s3.send(wasmCommand)

if (wasmResponse.$metadata.httpStatusCode !== 200)
throw new Error(`There was an error while trying to download the wasm file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`)

if (wasmResponse.Body instanceof Readable)
await streamPipeline(wasmResponse.Body, fs.createWriteStream(localWasmPath))
const responseWASM = await fetch(artifacts.wasmStoragePath)
if (!responseWASM.ok && responseWASM.status !== 200)
throw new Error(`There was an error while trying to download the WASM file for circuit ${circuitData.name}. Please check that the file has the correct permissions (public) set.`)
await streamPipeline(responseWASM.body!, createWriteStream(localWasmPath))

// validate that the circuit hash and template links are valid
const template = circuitData.template
Expand Down Expand Up @@ -239,8 +229,10 @@ export const parseCeremonyFile = async (path: string, cleanup: boolean = false):

circuits.push(circuit)

// remove the local r1cs download (if used for verifying the config only vs setup)
if (cleanup) fs.unlinkSync(localR1csPath)
// remove the local r1cs and wasm downloads (if used for verifying the config only vs setup)
if (cleanup)
fs.unlinkSync(localR1csPath)
fs.unlinkSync(localWasmPath)
}

const setupData: SetupCeremonyData = {
Expand Down
6 changes: 2 additions & 4 deletions packages/actions/test/data/artifacts/ceremonySetup.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@
"cfOrVm": "CF"
},
"artifacts": {
"bucket": "p0tion-test-definitely-setup",
"region": "us-east-1",
"r1csStoragePath": "circuit.r1cs",
"wasmStoragePath": "circuit.wasm"
"r1csStoragePath": "https://p0tion-test-definitely-setup.s3.amazonaws.com/circuit.r1cs",
"wasmStoragePath": "https://p0tion-test-definitely-setup.s3.amazonaws.com/circuit.wasm"
},
"name": "circuit",
"dynamicThreshold": 0,
Expand Down
91 changes: 0 additions & 91 deletions packages/actions/test/unit/security.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import {
signOut,
signInWithEmailAndPassword,
OAuthCredential,
GithubAuthProvider,
signInAnonymously
} from "firebase/auth"
import { where } from "firebase/firestore"
import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device"
import { randomBytes } from "crypto"
import { fakeCeremoniesData, fakeCircuitsData, fakeParticipantsData, fakeUsersData } from "../data/samples"
import {
Expand Down Expand Up @@ -60,7 +58,6 @@ import {
mockCeremoniesCleanup,
deleteAdminApp
} from "../utils"
import { simulateOnVerification } from "../utils/authentication"

chai.use(chaiAsPromised)

Expand Down Expand Up @@ -861,66 +858,6 @@ describe("Security", () => {
"Firebase: Invalid IdP response/credential: http://localhost?&providerId=undefined (auth/invalid-credential-or-provider-id)."
)
})
/// @note If a token has been invalidated, this shuold not allow to access Firebase again
/// @todo might not be able to test this in code since it requires revoking access on GitHub
it.skip("should not be able to authenticate with a token after this is invalidated", async () => {
const auth = createOAuthDeviceAuth({
clientType,
clientId,
scopes: ["gist"],
onVerification: simulateOnVerification
})
const { token } = await auth({
type: tokenType
})
// Get and exchange credentials.
const userFirebaseCredentials = GithubAuthProvider.credential(token)
await signInToFirebaseWithCredentials(userApp, userFirebaseCredentials)
const user = getCurrentFirebaseAuthUser(userApp)
userId = user.uid

await signOut(userAuth)

// @todo how to revoke the token programmatically?
await signInToFirebaseWithCredentials(userApp, userFirebaseCredentials)
})
/// @note A malicious user should not be able to create multiple malicious accounts
/// to spam a ceremony
// @todo requires adding the checks to the cloud function
it("should prevent a user with a non reputable GitHub account from authenticating to the Firebase", async () => {})
/// @note If a coordinator disables an account, this should not be allowed to authenticate
/// @note test requires a working OAuth2 emulation (puppeteer)
it.skip("should prevent a disabled account from loggin in (OAuth2)", async () => {
const auth = createOAuthDeviceAuth({
clientType,
clientId,
scopes: ["gist"],
onVerification: simulateOnVerification
})
const { token } = await auth({
type: tokenType
})
// Get and exchange credentials.
const userFirebaseCredentials = GithubAuthProvider.credential(token)
await signInToFirebaseWithCredentials(userApp, userFirebaseCredentials)

const user = getCurrentFirebaseAuthUser(userApp)
userId = user.uid
// Disable user.
const disabledRecord = await adminAuth.updateUser(user.uid, { disabled: true })
expect(disabledRecord.disabled).to.be.true

await signOut(userAuth)

await expect(signInToFirebaseWithCredentials(userApp, userFirebaseCredentials)).to.be.rejectedWith(
"Firebase: Error (auth/user-disabled)."
)

// Re-enable user.
// Disable user.
const reEnabledRecord = await adminAuth.updateUser(user.uid, { disabled: false })
expect(reEnabledRecord.disabled).to.be.false
})
/// @note Firebase should lock out an account after a large number of failed authentication attempts
/// to prevent brute force attacks
it("should lock out an account after a large number of failed attempts", async () => {
Expand All @@ -939,34 +876,6 @@ describe("Security", () => {
"FirebaseError: Firebase: Access to this account has been temporarily disabled due to many failed login attempts. You can immediately restore it by resetting your password or you can try again later. (auth/too-many-requests)."
)
})
it.skip("should error out and prevent further authentication attempts after authenticating with the correct OAuth2 token many times (could prevent other users from authenticating)", async () => {
let err: any
const auth = createOAuthDeviceAuth({
clientType,
clientId,
scopes: ["gist"],
onVerification: simulateOnVerification
})
const { token } = await auth({
type: tokenType
})
// Get and exchange credentials.
const userFirebaseCredentials = GithubAuthProvider.credential(token)
for (let i = 0; i < 1000; i++) {
try {
await signInToFirebaseWithCredentials(userApp, userFirebaseCredentials)
} catch (error: any) {
err = error
break
}
}
expect(
err.toString() === "FirebaseError: Firebase: Error (auth/user-disabled)." ||
err.toString() === "FirebaseError: Firebase: Error (auth/network-request-failed)." ||
err.toString() ===
"FirebaseError: Firebase: Malformed response cannot be parsed from github.com for USER_INFO (auth/invalid-credential)."
).to.be.true
})
/// @note Firebase should enforce rate limiting to prevent denial of service or consumption of resources
/// scenario where one user tries to authenticate many times consecutively with the correct details
/// to try and block the authentication service for other users
Expand Down
Loading
Loading