@devtion/backend 0.0.0-3df1645 → 0.0.0-477457c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/src/functions/index.js +627 -345
- package/dist/src/functions/index.mjs +628 -348
- package/dist/src/functions/types/functions/bandada.d.ts +4 -0
- package/dist/src/functions/types/functions/bandada.d.ts.map +1 -0
- package/dist/{types → src/functions/types}/functions/ceremony.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/circuit.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/index.d.ts +2 -0
- package/dist/{types → src/functions/types}/functions/index.d.ts.map +1 -1
- package/dist/src/functions/types/functions/siwe.d.ts +4 -0
- package/dist/src/functions/types/functions/siwe.d.ts.map +1 -0
- package/dist/{types → src/functions/types}/functions/storage.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/timeout.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/user.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/lib/errors.d.ts +2 -1
- package/dist/src/functions/types/lib/errors.d.ts.map +1 -0
- package/dist/{types → src/functions/types}/lib/services.d.ts +7 -0
- package/dist/src/functions/types/lib/services.d.ts.map +1 -0
- package/dist/src/functions/types/lib/utils.d.ts.map +1 -0
- package/dist/{types → src/functions/types}/types/index.d.ts +56 -0
- package/dist/src/functions/types/types/index.d.ts.map +1 -0
- package/package.json +8 -7
- package/src/functions/bandada.ts +154 -0
- package/src/functions/ceremony.ts +11 -7
- package/src/functions/circuit.ts +414 -384
- package/src/functions/index.ts +2 -0
- package/src/functions/participant.ts +8 -8
- package/src/functions/siwe.ts +77 -0
- package/src/functions/storage.ts +7 -6
- package/src/functions/timeout.ts +14 -13
- package/src/functions/user.ts +6 -5
- package/src/lib/errors.ts +6 -1
- package/src/lib/services.ts +36 -0
- package/src/lib/utils.ts +8 -6
- package/src/types/declarations.d.ts +1 -0
- package/src/types/index.ts +60 -0
- package/dist/types/lib/errors.d.ts.map +0 -1
- package/dist/types/lib/services.d.ts.map +0 -1
- package/dist/types/lib/utils.d.ts.map +0 -1
- package/dist/types/types/index.d.ts.map +0 -1
- /package/dist/{types → src/functions/types}/functions/ceremony.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/circuit.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/participant.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/participant.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/functions/storage.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/timeout.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/user.d.ts +0 -0
- /package/dist/{types → src/functions/types}/lib/utils.d.ts +0 -0
- /package/dist/{types → src/functions/types}/types/enums.d.ts +0 -0
- /package/dist/{types → src/functions/types}/types/enums.d.ts.map +0 -0
package/src/functions/index.ts
CHANGED
|
@@ -31,6 +31,8 @@ export {
|
|
|
31
31
|
generatePreSignedUrlsParts,
|
|
32
32
|
completeMultiPartUpload
|
|
33
33
|
} from "./storage"
|
|
34
|
+
export { bandadaValidateProof } from "./bandada"
|
|
35
|
+
export { checkNonceOfSIWEAddress } from "./siwe"
|
|
34
36
|
export { checkAndRemoveBlockingContributor, resumeContributionAfterTimeoutExpiration } from "./timeout"
|
|
35
37
|
|
|
36
38
|
admin.initializeApp()
|
|
@@ -46,7 +46,7 @@ dotenv.config()
|
|
|
46
46
|
export const checkParticipantForCeremony = functions
|
|
47
47
|
.region("europe-west1")
|
|
48
48
|
.runWith({
|
|
49
|
-
memory: "
|
|
49
|
+
memory: "1GB"
|
|
50
50
|
})
|
|
51
51
|
.https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext) => {
|
|
52
52
|
if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
|
|
@@ -134,7 +134,7 @@ export const checkParticipantForCeremony = functions
|
|
|
134
134
|
participantDoc.ref.update({
|
|
135
135
|
status: ParticipantStatus.EXHUMED,
|
|
136
136
|
contributions,
|
|
137
|
-
tempContributionData: tempContributionData
|
|
137
|
+
tempContributionData: tempContributionData || FieldValue.delete(),
|
|
138
138
|
contributionStep: ParticipantContributionStep.DOWNLOADING,
|
|
139
139
|
contributionStartedAt: 0,
|
|
140
140
|
verificationStartedAt: FieldValue.delete(),
|
|
@@ -177,7 +177,7 @@ export const checkParticipantForCeremony = functions
|
|
|
177
177
|
export const progressToNextCircuitForContribution = functions
|
|
178
178
|
.region("europe-west1")
|
|
179
179
|
.runWith({
|
|
180
|
-
memory: "
|
|
180
|
+
memory: "1GB"
|
|
181
181
|
})
|
|
182
182
|
.https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<void> => {
|
|
183
183
|
if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
|
|
@@ -235,7 +235,7 @@ export const progressToNextCircuitForContribution = functions
|
|
|
235
235
|
export const progressToNextContributionStep = functions
|
|
236
236
|
.region("europe-west1")
|
|
237
237
|
.runWith({
|
|
238
|
-
memory: "
|
|
238
|
+
memory: "1GB"
|
|
239
239
|
})
|
|
240
240
|
.https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext) => {
|
|
241
241
|
if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
|
|
@@ -298,7 +298,7 @@ export const progressToNextContributionStep = functions
|
|
|
298
298
|
export const permanentlyStoreCurrentContributionTimeAndHash = functions
|
|
299
299
|
.region("europe-west1")
|
|
300
300
|
.runWith({
|
|
301
|
-
memory: "
|
|
301
|
+
memory: "1GB"
|
|
302
302
|
})
|
|
303
303
|
.https.onCall(
|
|
304
304
|
async (data: PermanentlyStoreCurrentContributionTimeAndHash, context: functions.https.CallableContext) => {
|
|
@@ -357,7 +357,7 @@ export const permanentlyStoreCurrentContributionTimeAndHash = functions
|
|
|
357
357
|
export const temporaryStoreCurrentContributionMultiPartUploadId = functions
|
|
358
358
|
.region("europe-west1")
|
|
359
359
|
.runWith({
|
|
360
|
-
memory: "
|
|
360
|
+
memory: "1GB"
|
|
361
361
|
})
|
|
362
362
|
.https.onCall(
|
|
363
363
|
async (data: TemporaryStoreCurrentContributionMultiPartUploadId, context: functions.https.CallableContext) => {
|
|
@@ -411,7 +411,7 @@ export const temporaryStoreCurrentContributionMultiPartUploadId = functions
|
|
|
411
411
|
export const temporaryStoreCurrentContributionUploadedChunkData = functions
|
|
412
412
|
.region("europe-west1")
|
|
413
413
|
.runWith({
|
|
414
|
-
memory: "
|
|
414
|
+
memory: "1GB"
|
|
415
415
|
})
|
|
416
416
|
.https.onCall(
|
|
417
417
|
async (data: TemporaryStoreCurrentContributionUploadedChunkData, context: functions.https.CallableContext) => {
|
|
@@ -471,7 +471,7 @@ export const temporaryStoreCurrentContributionUploadedChunkData = functions
|
|
|
471
471
|
export const checkAndPrepareCoordinatorForFinalization = functions
|
|
472
472
|
.region("europe-west1")
|
|
473
473
|
.runWith({
|
|
474
|
-
memory: "
|
|
474
|
+
memory: "1GB"
|
|
475
475
|
})
|
|
476
476
|
.https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<boolean> => {
|
|
477
477
|
if (!context.auth || !context.auth.token.coordinator) logAndThrowError(COMMON_ERRORS.CM_NOT_COORDINATOR_ROLE)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import dotenv from "dotenv"
|
|
2
|
+
import fetch from "@adobe/node-fetch-retry"
|
|
3
|
+
import * as functions from "firebase-functions"
|
|
4
|
+
import { getAuth } from "firebase-admin/auth"
|
|
5
|
+
import admin from "firebase-admin"
|
|
6
|
+
import { Auth0UserInfo, CheckNonceOfSIWEAddressRequest, CheckNonceOfSIWEAddressResponse } from "../types"
|
|
7
|
+
import { setEthProvider } from "../lib/services"
|
|
8
|
+
|
|
9
|
+
dotenv.config()
|
|
10
|
+
|
|
11
|
+
export const checkNonceOfSIWEAddress = functions
|
|
12
|
+
.region("europe-west1")
|
|
13
|
+
.runWith({ memory: "1GB" })
|
|
14
|
+
.https.onCall(async (data: CheckNonceOfSIWEAddressRequest): Promise<CheckNonceOfSIWEAddressResponse> => {
|
|
15
|
+
try {
|
|
16
|
+
const { auth0Token } = data
|
|
17
|
+
const result = (await fetch(`${process.env.AUTH0_APPLICATION_URL}/userinfo`, {
|
|
18
|
+
method: "GET",
|
|
19
|
+
headers: {
|
|
20
|
+
"content-type": "application/json",
|
|
21
|
+
authorization: `Bearer ${auth0Token}`
|
|
22
|
+
}
|
|
23
|
+
}).then((_res) => _res.json())) as Auth0UserInfo
|
|
24
|
+
if (!result.sub) {
|
|
25
|
+
return {
|
|
26
|
+
valid: false,
|
|
27
|
+
message: "No user detected. Please check device flow token"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const auth = getAuth()
|
|
31
|
+
// check nonce
|
|
32
|
+
const parts = result.sub.split("|")
|
|
33
|
+
const address = decodeURIComponent(parts[2]).split(":")[2]
|
|
34
|
+
|
|
35
|
+
const minimumNonce = Number(process.env.ETH_MINIMUM_NONCE)
|
|
36
|
+
const nonceBlockHeight = "latest" // process.env.ETH_NONCE_BLOCK_HEIGHT
|
|
37
|
+
// look up nonce for address @block
|
|
38
|
+
let nonceOk = true
|
|
39
|
+
if (minimumNonce > 0) {
|
|
40
|
+
const provider = setEthProvider()
|
|
41
|
+
console.log(`got provider - block # ${await provider.getBlockNumber()}`)
|
|
42
|
+
const nonce = await provider.getTransactionCount(address, nonceBlockHeight)
|
|
43
|
+
console.log(`nonce ${nonce}`)
|
|
44
|
+
nonceOk = nonce >= minimumNonce
|
|
45
|
+
}
|
|
46
|
+
console.log(`checking nonce ${nonceOk}`)
|
|
47
|
+
if (!nonceOk) {
|
|
48
|
+
return {
|
|
49
|
+
valid: false,
|
|
50
|
+
message: "Eth address does not meet the nonce requirements"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
await admin.auth().createUser({
|
|
55
|
+
displayName: address,
|
|
56
|
+
uid: address
|
|
57
|
+
})
|
|
58
|
+
} catch (error: any) {
|
|
59
|
+
// if user already exist then just pass
|
|
60
|
+
if (error.code !== "auth/uid-already-exists") {
|
|
61
|
+
throw new Error(error)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const token = await auth.createCustomToken(address)
|
|
65
|
+
return {
|
|
66
|
+
valid: true,
|
|
67
|
+
token
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return {
|
|
71
|
+
valid: false,
|
|
72
|
+
message: `Something went wrong ${error}`
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
export default checkNonceOfSIWEAddress
|
package/src/functions/storage.ts
CHANGED
|
@@ -134,7 +134,7 @@ const checkIfBucketIsDedicatedToCeremony = async (bucketName: string) => {
|
|
|
134
134
|
export const createBucket = functions
|
|
135
135
|
.region("europe-west1")
|
|
136
136
|
.runWith({
|
|
137
|
-
memory: "
|
|
137
|
+
memory: "1GB"
|
|
138
138
|
})
|
|
139
139
|
.https.onCall(async (data: CreateBucketData, context: functions.https.CallableContext) => {
|
|
140
140
|
// Check if the user has the coordinator claim.
|
|
@@ -146,6 +146,7 @@ export const createBucket = functions
|
|
|
146
146
|
const S3 = await getS3Client()
|
|
147
147
|
|
|
148
148
|
try {
|
|
149
|
+
printLog(`Creating AWS S3 bucket ${data.bucketName} ...`, LogLevel.LOG)
|
|
149
150
|
// Try to get information about the bucket.
|
|
150
151
|
await S3.send(new HeadBucketCommand({ Bucket: data.bucketName }))
|
|
151
152
|
// If the command succeeded, the bucket exists, throw an error.
|
|
@@ -238,7 +239,7 @@ export const createBucket = functions
|
|
|
238
239
|
export const checkIfObjectExist = functions
|
|
239
240
|
.region("europe-west1")
|
|
240
241
|
.runWith({
|
|
241
|
-
memory: "
|
|
242
|
+
memory: "1GB"
|
|
242
243
|
})
|
|
243
244
|
.https.onCall(async (data: BucketAndObjectKeyData, context: functions.https.CallableContext): Promise<boolean> => {
|
|
244
245
|
// Check if the user has the coordinator claim.
|
|
@@ -294,7 +295,7 @@ export const checkIfObjectExist = functions
|
|
|
294
295
|
export const generateGetObjectPreSignedUrl = functions
|
|
295
296
|
.region("europe-west1")
|
|
296
297
|
.runWith({
|
|
297
|
-
memory: "
|
|
298
|
+
memory: "1GB"
|
|
298
299
|
})
|
|
299
300
|
.https.onCall(async (data: BucketAndObjectKeyData, context: functions.https.CallableContext): Promise<any> => {
|
|
300
301
|
if (!context.auth) logAndThrowError(COMMON_ERRORS.CM_NOT_AUTHENTICATED)
|
|
@@ -341,7 +342,7 @@ export const generateGetObjectPreSignedUrl = functions
|
|
|
341
342
|
export const startMultiPartUpload = functions
|
|
342
343
|
.region("europe-west1")
|
|
343
344
|
.runWith({
|
|
344
|
-
memory: "
|
|
345
|
+
memory: "2GB"
|
|
345
346
|
})
|
|
346
347
|
.https.onCall(async (data: StartMultiPartUploadData, context: functions.https.CallableContext): Promise<any> => {
|
|
347
348
|
if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
|
|
@@ -409,7 +410,7 @@ export const startMultiPartUpload = functions
|
|
|
409
410
|
export const generatePreSignedUrlsParts = functions
|
|
410
411
|
.region("europe-west1")
|
|
411
412
|
.runWith({
|
|
412
|
-
memory: "
|
|
413
|
+
memory: "1GB",
|
|
413
414
|
timeoutSeconds: 300
|
|
414
415
|
})
|
|
415
416
|
.https.onCall(
|
|
@@ -487,7 +488,7 @@ export const generatePreSignedUrlsParts = functions
|
|
|
487
488
|
export const completeMultiPartUpload = functions
|
|
488
489
|
.region("europe-west1")
|
|
489
490
|
.runWith({
|
|
490
|
-
memory: "
|
|
491
|
+
memory: "2GB"
|
|
491
492
|
})
|
|
492
493
|
.https.onCall(async (data: CompleteMultiPartUploadData, context: functions.https.CallableContext): Promise<any> => {
|
|
493
494
|
if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
|
package/src/functions/timeout.ts
CHANGED
|
@@ -42,7 +42,7 @@ dotenv.config()
|
|
|
42
42
|
export const checkAndRemoveBlockingContributor = functions
|
|
43
43
|
.region("europe-west1")
|
|
44
44
|
.runWith({
|
|
45
|
-
memory: "
|
|
45
|
+
memory: "1GB"
|
|
46
46
|
})
|
|
47
47
|
.pubsub.schedule("every 1 minutes")
|
|
48
48
|
.onRun(async () => {
|
|
@@ -64,7 +64,7 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
64
64
|
const circuits = await getCeremonyCircuits(ceremony.id)
|
|
65
65
|
|
|
66
66
|
// Extract ceremony data.
|
|
67
|
-
const { timeoutMechanismType, penalty } = ceremony.data()!
|
|
67
|
+
const { timeoutType: timeoutMechanismType, penalty } = ceremony.data()!
|
|
68
68
|
|
|
69
69
|
for (const circuit of circuits) {
|
|
70
70
|
if (!circuit.data())
|
|
@@ -86,7 +86,7 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
86
86
|
// Do not use `logAndThrowError` method to avoid the function to exit before checking every ceremony.
|
|
87
87
|
printLog(
|
|
88
88
|
`No current contributor for circuit ${circuit.id} - ceremony ${ceremony.id}`,
|
|
89
|
-
LogLevel.
|
|
89
|
+
LogLevel.DEBUG
|
|
90
90
|
)
|
|
91
91
|
else if (
|
|
92
92
|
avgFullContribution === 0 &&
|
|
@@ -128,7 +128,7 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
128
128
|
? Number(contributionStartedAt) +
|
|
129
129
|
Number(avgFullContribution) +
|
|
130
130
|
Number(timeoutDynamicThreshold)
|
|
131
|
-
: Number(contributionStartedAt) + Number(fixedTimeWindow) * 60000 // * 60000 = convert minutes to millis.
|
|
131
|
+
: (Number(contributionStartedAt) + Number(fixedTimeWindow)) * 60000 // * 60000 = convert minutes to millis.
|
|
132
132
|
|
|
133
133
|
// Case (D).
|
|
134
134
|
const timeoutExpirationDateInMsForVerificationCloudFunction =
|
|
@@ -144,7 +144,8 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
144
144
|
timeoutExpirationDateInMsForBlockingContributor < currentServerTimestamp &&
|
|
145
145
|
(contributionStep === ParticipantContributionStep.DOWNLOADING ||
|
|
146
146
|
contributionStep === ParticipantContributionStep.COMPUTING ||
|
|
147
|
-
contributionStep === ParticipantContributionStep.UPLOADING
|
|
147
|
+
contributionStep === ParticipantContributionStep.UPLOADING ||
|
|
148
|
+
contributionStep === ParticipantContributionStep.COMPLETED)
|
|
148
149
|
)
|
|
149
150
|
timeoutType = TimeoutType.BLOCKING_CONTRIBUTION
|
|
150
151
|
|
|
@@ -155,18 +156,18 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
155
156
|
)
|
|
156
157
|
timeoutType = TimeoutType.BLOCKING_CLOUD_FUNCTION
|
|
157
158
|
|
|
158
|
-
printLog(
|
|
159
|
-
`${timeoutType} detected for circuit ${circuit.id} - ceremony ${ceremony.id}`,
|
|
160
|
-
LogLevel.DEBUG
|
|
161
|
-
)
|
|
162
|
-
|
|
163
159
|
if (!timeoutType)
|
|
164
160
|
// Do not use `logAndThrowError` method to avoid the function to exit before checking every ceremony.
|
|
165
161
|
printLog(
|
|
166
162
|
`No timeout for circuit ${circuit.id} - ceremony ${ceremony.id}`,
|
|
167
|
-
LogLevel.
|
|
163
|
+
LogLevel.DEBUG
|
|
168
164
|
)
|
|
169
165
|
else {
|
|
166
|
+
printLog(
|
|
167
|
+
`${timeoutType} detected for circuit ${circuit.id} - ceremony ${ceremony.id}`,
|
|
168
|
+
LogLevel.WARN
|
|
169
|
+
)
|
|
170
|
+
|
|
170
171
|
// Case (E).
|
|
171
172
|
let nextCurrentContributorId = ""
|
|
172
173
|
|
|
@@ -235,7 +236,7 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
235
236
|
|
|
236
237
|
printLog(
|
|
237
238
|
`The contributor ${participant.id} has been identified as potential blocking contributor. A timeout of type ${timeoutType} has been triggered w/ a penalty of ${timeoutPenaltyInMs} ms`,
|
|
238
|
-
LogLevel.
|
|
239
|
+
LogLevel.WARN
|
|
239
240
|
)
|
|
240
241
|
}
|
|
241
242
|
}
|
|
@@ -253,7 +254,7 @@ export const checkAndRemoveBlockingContributor = functions
|
|
|
253
254
|
export const resumeContributionAfterTimeoutExpiration = functions
|
|
254
255
|
.region("europe-west1")
|
|
255
256
|
.runWith({
|
|
256
|
-
memory: "
|
|
257
|
+
memory: "1GB"
|
|
257
258
|
})
|
|
258
259
|
.https.onCall(async (data: { ceremonyId: string }, context: functions.https.CallableContext): Promise<void> => {
|
|
259
260
|
if (!context.auth || (!context.auth.token.participant && !context.auth.token.coordinator))
|
package/src/functions/user.ts
CHANGED
|
@@ -18,7 +18,7 @@ dotenv.config()
|
|
|
18
18
|
export const registerAuthUser = functions
|
|
19
19
|
.region("europe-west1")
|
|
20
20
|
.runWith({
|
|
21
|
-
memory: "
|
|
21
|
+
memory: "1GB"
|
|
22
22
|
})
|
|
23
23
|
.auth.user()
|
|
24
24
|
.onCreate(async (user: UserRecord) => {
|
|
@@ -55,7 +55,7 @@ export const registerAuthUser = functions
|
|
|
55
55
|
) {
|
|
56
56
|
const auth = admin.auth()
|
|
57
57
|
// if provider == github.com let's use our functions to check the user's reputation
|
|
58
|
-
if (user.providerData[0].providerId === "github.com") {
|
|
58
|
+
if (user.providerData.length > 0 && user.providerData[0].providerId === "github.com") {
|
|
59
59
|
const vars = getGitHubVariables()
|
|
60
60
|
|
|
61
61
|
// this return true or false
|
|
@@ -64,7 +64,8 @@ export const registerAuthUser = functions
|
|
|
64
64
|
user.providerData[0].uid,
|
|
65
65
|
vars.minimumFollowing,
|
|
66
66
|
vars.minimumFollowers,
|
|
67
|
-
vars.minimumPublicRepos
|
|
67
|
+
vars.minimumPublicRepos,
|
|
68
|
+
vars.minimumAge
|
|
68
69
|
)
|
|
69
70
|
if (!reputable) {
|
|
70
71
|
// Delete user
|
|
@@ -111,7 +112,7 @@ export const registerAuthUser = functions
|
|
|
111
112
|
encodedDisplayName,
|
|
112
113
|
// Metadata.
|
|
113
114
|
creationTime,
|
|
114
|
-
lastSignInTime,
|
|
115
|
+
lastSignInTime: lastSignInTime || creationTime,
|
|
115
116
|
// Optional.
|
|
116
117
|
email: email || "",
|
|
117
118
|
emailVerified: emailVerified || false,
|
|
@@ -135,7 +136,7 @@ export const registerAuthUser = functions
|
|
|
135
136
|
export const processSignUpWithCustomClaims = functions
|
|
136
137
|
.region("europe-west1")
|
|
137
138
|
.runWith({
|
|
138
|
-
memory: "
|
|
139
|
+
memory: "1GB"
|
|
139
140
|
})
|
|
140
141
|
.auth.user()
|
|
141
142
|
.onCreate(async (user: UserRecord) => {
|
package/src/lib/errors.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { LogLevel } from "../types/enums"
|
|
|
7
7
|
* @notice the set of Firebase Functions status codes. The codes are the same at the
|
|
8
8
|
* ones exposed by {@link https://github.com/grpc/grpc/blob/master/doc/statuscodes.md | gRPC}.
|
|
9
9
|
* @param errorCode <FunctionsErrorCode> - the set of possible error codes.
|
|
10
|
-
* @param message <string> - the error
|
|
10
|
+
* @param message <string> - the error message.
|
|
11
11
|
* @param [details] <string> - the details of the error (optional).
|
|
12
12
|
* @returns <HttpsError>
|
|
13
13
|
*/
|
|
@@ -189,6 +189,11 @@ export const SPECIFIC_ERRORS = {
|
|
|
189
189
|
"unavailable",
|
|
190
190
|
"VM command execution has failed due to an unknown status code",
|
|
191
191
|
"Please, contact the coordinator if this error persists."
|
|
192
|
+
),
|
|
193
|
+
WRONG_BUCKET_NAME: makeError(
|
|
194
|
+
"invalid-argument",
|
|
195
|
+
"The provided bucket name is not valid.",
|
|
196
|
+
"Bucket names must be between 3 and 63 characters long, can only contain lowercase letters, numbers, and hyphens, and must start and end with a letter or number."
|
|
192
197
|
)
|
|
193
198
|
}
|
|
194
199
|
|
package/src/lib/services.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import dotenv from "dotenv"
|
|
2
|
+
import ethers from "ethers"
|
|
1
3
|
import { S3Client } from "@aws-sdk/client-s3"
|
|
2
4
|
import { COMMON_ERRORS, logAndThrowError } from "./errors"
|
|
3
5
|
|
|
6
|
+
dotenv.config()
|
|
7
|
+
let provider: ethers.providers.Provider
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
* Return a configured and connected instance of the AWS S3 client.
|
|
6
11
|
* @dev this method check and utilize the environment variables to configure the connection
|
|
@@ -26,3 +31,34 @@ export const getS3Client = async (): Promise<S3Client> => {
|
|
|
26
31
|
region: process.env.AWS_REGION!
|
|
27
32
|
})
|
|
28
33
|
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns a Prvider, connected via a configured JSON URL or else
|
|
37
|
+
* the ethers.js default provider, using configured API keys.
|
|
38
|
+
* @returns <ethers.providers.Provider> An Eth node provider
|
|
39
|
+
*/
|
|
40
|
+
export const setEthProvider = (): ethers.providers.Provider => {
|
|
41
|
+
if (provider) return provider
|
|
42
|
+
console.log(`setting new provider`)
|
|
43
|
+
|
|
44
|
+
// Use JSON URL if defined
|
|
45
|
+
// if ((hardhat as any).ethers) {
|
|
46
|
+
// console.log(`using hardhat.ethers provider`)
|
|
47
|
+
// provider = (hardhat as any).ethers.provider
|
|
48
|
+
// } else
|
|
49
|
+
if (process.env.ETH_PROVIDER_JSON_URL) {
|
|
50
|
+
console.log(`JSON URL provider at ${process.env.ETH_PROVIDER_JSON_URL}`)
|
|
51
|
+
provider = new ethers.providers.JsonRpcProvider({
|
|
52
|
+
url: process.env.ETH_PROVIDER_JSON_URL,
|
|
53
|
+
skipFetchSetup: true
|
|
54
|
+
})
|
|
55
|
+
} else {
|
|
56
|
+
// Otherwise, connect the default provider with ALchemy, Infura, or both
|
|
57
|
+
provider = ethers.providers.getDefaultProvider("homestead", {
|
|
58
|
+
alchemy: process.env.ETH_PROVIDER_ALCHEMY_API_KEY!,
|
|
59
|
+
infura: process.env.ETH_PROVIDER_INFURA_API_KEY!
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return provider
|
|
64
|
+
}
|
package/src/lib/utils.ts
CHANGED
|
@@ -10,7 +10,7 @@ import admin from "firebase-admin"
|
|
|
10
10
|
import dotenv from "dotenv"
|
|
11
11
|
import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3"
|
|
12
12
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
|
|
13
|
-
import { createWriteStream
|
|
13
|
+
import { createWriteStream } from "node:fs"
|
|
14
14
|
import { pipeline } from "node:stream"
|
|
15
15
|
import { promisify } from "node:util"
|
|
16
16
|
import { readFileSync } from "fs"
|
|
@@ -166,7 +166,7 @@ export const getCircuitDocumentByPosition = async (
|
|
|
166
166
|
// Query for all ceremony circuits.
|
|
167
167
|
const circuits = await getCeremonyCircuits(ceremonyId)
|
|
168
168
|
|
|
169
|
-
// Apply a filter using the sequence
|
|
169
|
+
// Apply a filter using the sequence position.
|
|
170
170
|
const matchedCircuits = circuits.filter(
|
|
171
171
|
(circuit: DocumentData) => circuit.data().sequencePosition === sequencePosition
|
|
172
172
|
)
|
|
@@ -385,14 +385,16 @@ export const getGitHubVariables = (): any => {
|
|
|
385
385
|
if (
|
|
386
386
|
!process.env.GITHUB_MINIMUM_FOLLOWERS ||
|
|
387
387
|
!process.env.GITHUB_MINIMUM_FOLLOWING ||
|
|
388
|
-
!process.env.GITHUB_MINIMUM_PUBLIC_REPOS
|
|
388
|
+
!process.env.GITHUB_MINIMUM_PUBLIC_REPOS ||
|
|
389
|
+
!process.env.GITHUB_MINIMUM_AGE
|
|
389
390
|
)
|
|
390
391
|
logAndThrowError(COMMON_ERRORS.CM_WRONG_CONFIGURATION)
|
|
391
392
|
|
|
392
393
|
return {
|
|
393
394
|
minimumFollowers: Number(process.env.GITHUB_MINIMUM_FOLLOWERS),
|
|
394
395
|
minimumFollowing: Number(process.env.GITHUB_MINIMUM_FOLLOWING),
|
|
395
|
-
minimumPublicRepos: Number(process.env.GITHUB_MINIMUM_PUBLIC_REPOS)
|
|
396
|
+
minimumPublicRepos: Number(process.env.GITHUB_MINIMUM_PUBLIC_REPOS),
|
|
397
|
+
minimumAge: Number(process.env.GITHUB_MINIMUM_AGE)
|
|
396
398
|
}
|
|
397
399
|
}
|
|
398
400
|
|
|
@@ -404,7 +406,7 @@ export const getAWSVariables = (): any => {
|
|
|
404
406
|
if (
|
|
405
407
|
!process.env.AWS_ACCESS_KEY_ID ||
|
|
406
408
|
!process.env.AWS_SECRET_ACCESS_KEY ||
|
|
407
|
-
!process.env.
|
|
409
|
+
!process.env.AWS_INSTANCE_PROFILE_ARN ||
|
|
408
410
|
!process.env.AWS_AMI_ID ||
|
|
409
411
|
!process.env.AWS_SNS_TOPIC_ARN
|
|
410
412
|
)
|
|
@@ -414,7 +416,7 @@ export const getAWSVariables = (): any => {
|
|
|
414
416
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
415
417
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
416
418
|
region: process.env.AWS_REGION || "eu-central-1",
|
|
417
|
-
|
|
419
|
+
instanceProfileArn: process.env.AWS_INSTANCE_PROFILE_ARN!,
|
|
418
420
|
amiId: process.env.AWS_AMI_ID!,
|
|
419
421
|
snsTopic: process.env.AWS_SNS_TOPIC_ARN!
|
|
420
422
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module "@bandada/api-sdk"
|
package/src/types/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CeremonyInputData, CircuitDocument, ETagWithPartNumber } from "@devtion/actions"
|
|
2
|
+
import type { Groth16Proof, PublicSignals } from "snarkjs"
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Group all the necessary data needed for running the `setupCeremony` cloud function.
|
|
@@ -138,3 +139,62 @@ export type FinalizeCircuitData = {
|
|
|
138
139
|
bucketName: string
|
|
139
140
|
beacon: string
|
|
140
141
|
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Group all the necessary data needed for running the `bandadaValidateProof` cloud function.
|
|
145
|
+
* @typedef {Object} BandadaValidateProof
|
|
146
|
+
* @property {string} merkleTreeRoot - the merkle tree root of the group.
|
|
147
|
+
* @property {string} nullifierHash - the nullifier hash of the member.
|
|
148
|
+
* @property {string} externalNullifier - the external nullifier of the member.
|
|
149
|
+
* @property {PackedProof} proof - the packed proof generated on the client.
|
|
150
|
+
*/
|
|
151
|
+
export type BandadaValidateProof = {
|
|
152
|
+
proof: Groth16Proof
|
|
153
|
+
publicSignals: PublicSignals
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Define the return object of the function that verifies the Bandada membership and proof.
|
|
158
|
+
* @typedef {Object} VerifiedBandadaResponse
|
|
159
|
+
* @property {boolean} valid - true if the proof is valid and the user is a member of the group; otherwise false.
|
|
160
|
+
* @property {string} message - a message describing the result of the verification.
|
|
161
|
+
* @property {string} token - the custom access token.
|
|
162
|
+
*/
|
|
163
|
+
export type VerifiedBandadaResponse = {
|
|
164
|
+
valid: boolean
|
|
165
|
+
message: string
|
|
166
|
+
token: string
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Define the check nonce object for the cloud function
|
|
171
|
+
* @typedef {Object} CheckNonceOfSIWEAddressRequest
|
|
172
|
+
* @property {string} auth0Token - token from the device flow authentication
|
|
173
|
+
*/
|
|
174
|
+
export type CheckNonceOfSIWEAddressRequest = {
|
|
175
|
+
auth0Token: string
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Define the check nonce response object of the cloud function
|
|
180
|
+
* @typedef {Object} CheckNonceOfSIWEAddressResponse
|
|
181
|
+
* @property {boolean} valid - if the checking result was valid or not
|
|
182
|
+
* @property {string} message - informative message
|
|
183
|
+
* @property {string} token - token to sign in
|
|
184
|
+
*/
|
|
185
|
+
export type CheckNonceOfSIWEAddressResponse = {
|
|
186
|
+
valid: boolean
|
|
187
|
+
message?: string
|
|
188
|
+
token?: string
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Define the response from auth0 /userinfo endpoint
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
export type Auth0UserInfo = {
|
|
195
|
+
sub: string
|
|
196
|
+
nickname: string
|
|
197
|
+
name: string
|
|
198
|
+
picture: string
|
|
199
|
+
updated_at: string
|
|
200
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,cAAe,kBAAkB,WAAW,MAAM,YAAY,MAAM,KAAG,UAC9B,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,QAAQ,YAAa,MAAM,YAAY,QAAQ,SAqB3D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,UAAW,UAAU,UAGjD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuI3B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;CA2CzB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../../src/lib/services.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C;;;;;GAKG;AACH,eAAO,MAAM,WAAW,QAAa,QAAQ,QAAQ,CAkBpD,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EAErB,aAAa,EAChB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAWlC,OAAO,EAOH,eAAe,EAClB,MAAM,iBAAiB,CAAA;AAIxB,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAM/C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,eACZ,MAAM,cACN,MAAM,KACnB,QAAQ,iBAAiB,YAAY,CAAC,CASxC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAO,MAAoC,CAAA;AAEzF;;;GAGG;AACH,eAAO,MAAM,KAAK,OAAc,MAAM,KAAG,QAAQ,IAAI,CAAmB,CAAA;AAExE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,eAAsB,MAAM,KAAG,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAYhH,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,eAC5B,MAAM,aACP,MAAM,KAClB,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAUpD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eACpB,MAAM,iBACH,MAAM,KACtB,QAAQ,cAAc,YAAY,CAAC,CASrC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAa,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAWhG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,eACzB,MAAM,oBACA,MAAM,KACzB,QAAQ,sBAAsB,YAAY,CAAC,CAY7C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,qBAAsB,MAAM,KAAG,MAAkD,CAAA;AAEtH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,eAAsB,MAAM,aAAa,MAAM,iBAAiB,MAAM,kBA6B9G,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,eACf,MAAM,aACP,MAAM,iBACF,MAAM,aACX,OAAO,kBA4BpB,CAAA;AAED,eAAO,MAAM,wBAAwB,eACrB,MAAM,aACP,MAAM,QACX,MAAM,aACF,OAAO,kBAyBpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAsB,MAAM,aAAa,MAAM,kBAWvE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,UAC/B,MAAM,wBACS,OAAO,SACtB,aAAa,KACrB,QAAQ,MAAM,SAAS,cAAc,CAAC,MAAM,SAAS,aAAa,CAAC,CAYxD,CAAA;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,eACjB,MAAM,aACP,MAAM,KAClB,QAAQ,sBAAsB,YAAY,CAAC,CAgB7C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,oBAAqB,eAAe,KAAG,eAKvE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,GAarC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,GAkBlC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAa,QAAQ,SAAS,CAYzD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAa,QAAQ,SAAS,CAYzD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,cAAqB,MAAM,KAAG,QAAQ,MAAM,CAQxE,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAExF;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;CACnC,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,sBAAsB,GAAG;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,8BAA8B,GAAG,sBAAsB,GAAG;IAClE,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,2BAA2B,GAAG,sBAAsB,GAAG;IAC/D,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,8CAA8C,GAAG;IACzD,UAAU,EAAE,MAAM,CAAA;IAClB,2BAA2B,EAAE,MAAM,CAAA;IACnC,gBAAgB,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC7D,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC7D,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,kBAAkB,CAAA;CAC5B,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC,EAAE,MAAM,CAAA;CAC7C,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;CACjB,CAAA"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|