@devtion/backend 0.0.0-56ecf35 → 0.0.0-57a8ab9

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.
@@ -31,6 +31,8 @@ var functionsV1 = require('firebase-functions/v1');
31
31
  var functionsV2 = require('firebase-functions/v2');
32
32
  var timerNode = require('timer-node');
33
33
  var snarkjs = require('snarkjs');
34
+ var apiSdk = require('@bandada/api-sdk');
35
+ var auth = require('firebase-admin/auth');
34
36
 
35
37
  function _interopNamespaceDefault(e) {
36
38
  var n = Object.create(null);
@@ -556,7 +558,7 @@ const registerAuthUser = functions__namespace
556
558
  email === process.env.CUSTOM_CLAIMS_COORDINATOR_EMAIL_ADDRESS_OR_DOMAIN)) {
557
559
  const auth = admin.auth();
558
560
  // if provider == github.com let's use our functions to check the user's reputation
559
- if (user.providerData[0].providerId === "github.com") {
561
+ if (user.providerData.length > 0 && user.providerData[0].providerId === "github.com") {
560
562
  const vars = getGitHubVariables();
561
563
  // this return true or false
562
564
  try {
@@ -588,7 +590,7 @@ const registerAuthUser = functions__namespace
588
590
  encodedDisplayName,
589
591
  // Metadata.
590
592
  creationTime,
591
- lastSignInTime,
593
+ lastSignInTime: lastSignInTime || creationTime,
592
594
  // Optional.
593
595
  email: email || "",
594
596
  emailVerified: emailVerified || false,
@@ -2407,6 +2409,148 @@ const completeMultiPartUpload = functions__namespace
2407
2409
  }
2408
2410
  });
2409
2411
 
2412
+ const VKEY_DATA = {
2413
+ protocol: "groth16",
2414
+ curve: "bn128",
2415
+ nPublic: 3,
2416
+ vk_alpha_1: [
2417
+ "20491192805390485299153009773594534940189261866228447918068658471970481763042",
2418
+ "9383485363053290200918347156157836566562967994039712273449902621266178545958",
2419
+ "1"
2420
+ ],
2421
+ vk_beta_2: [
2422
+ [
2423
+ "6375614351688725206403948262868962793625744043794305715222011528459656738731",
2424
+ "4252822878758300859123897981450591353533073413197771768651442665752259397132"
2425
+ ],
2426
+ [
2427
+ "10505242626370262277552901082094356697409835680220590971873171140371331206856",
2428
+ "21847035105528745403288232691147584728191162732299865338377159692350059136679"
2429
+ ],
2430
+ ["1", "0"]
2431
+ ],
2432
+ vk_gamma_2: [
2433
+ [
2434
+ "10857046999023057135944570762232829481370756359578518086990519993285655852781",
2435
+ "11559732032986387107991004021392285783925812861821192530917403151452391805634"
2436
+ ],
2437
+ [
2438
+ "8495653923123431417604973247489272438418190587263600148770280649306958101930",
2439
+ "4082367875863433681332203403145435568316851327593401208105741076214120093531"
2440
+ ],
2441
+ ["1", "0"]
2442
+ ],
2443
+ vk_delta_2: [
2444
+ [
2445
+ "3697618915467790705869942236922063775466274665053173890632463796679068973252",
2446
+ "14948341351907992175709156460547989243732741534604949238422596319735704165658"
2447
+ ],
2448
+ [
2449
+ "3028459181652799888716942141752307629938889957960373621898607910203491239368",
2450
+ "11380736494786911280692284374675752681598754560757720296073023058533044108340"
2451
+ ],
2452
+ ["1", "0"]
2453
+ ],
2454
+ vk_alphabeta_12: [
2455
+ [
2456
+ [
2457
+ "2029413683389138792403550203267699914886160938906632433982220835551125967885",
2458
+ "21072700047562757817161031222997517981543347628379360635925549008442030252106"
2459
+ ],
2460
+ [
2461
+ "5940354580057074848093997050200682056184807770593307860589430076672439820312",
2462
+ "12156638873931618554171829126792193045421052652279363021382169897324752428276"
2463
+ ],
2464
+ [
2465
+ "7898200236362823042373859371574133993780991612861777490112507062703164551277",
2466
+ "7074218545237549455313236346927434013100842096812539264420499035217050630853"
2467
+ ]
2468
+ ],
2469
+ [
2470
+ [
2471
+ "7077479683546002997211712695946002074877511277312570035766170199895071832130",
2472
+ "10093483419865920389913245021038182291233451549023025229112148274109565435465"
2473
+ ],
2474
+ [
2475
+ "4595479056700221319381530156280926371456704509942304414423590385166031118820",
2476
+ "19831328484489333784475432780421641293929726139240675179672856274388269393268"
2477
+ ],
2478
+ [
2479
+ "11934129596455521040620786944827826205713621633706285934057045369193958244500",
2480
+ "8037395052364110730298837004334506829870972346962140206007064471173334027475"
2481
+ ]
2482
+ ]
2483
+ ],
2484
+ IC: [
2485
+ [
2486
+ "12951059800758687233303204819298121944551181861362200875212570257618182506154",
2487
+ "5751958719396509176593242305268064754837298673622815112953832050159760501392",
2488
+ "1"
2489
+ ],
2490
+ [
2491
+ "9561588427935871983444704959674198910445823619407211599507208879011862515257",
2492
+ "14576201570478094842467636169770180675293504492823217349086195663150934064643",
2493
+ "1"
2494
+ ],
2495
+ [
2496
+ "4811967233483727873912563574622036989372099129165459921963463310078093941559",
2497
+ "1874883809855039536107616044787862082553628089593740724610117059083415551067",
2498
+ "1"
2499
+ ],
2500
+ [
2501
+ "12252730267779308452229639835051322390696643456253768618882001876621526827161",
2502
+ "7899194018737016222260328309937800777948677569409898603827268776967707173231",
2503
+ "1"
2504
+ ]
2505
+ ]
2506
+ };
2507
+ dotenv.config();
2508
+ const { BANDADA_API_URL, BANDADA_GROUP_ID } = process.env;
2509
+ const bandadaApi = new apiSdk.ApiSdk(BANDADA_API_URL);
2510
+ const bandadaValidateProof = functions__namespace
2511
+ .region("europe-west1")
2512
+ .runWith({
2513
+ memory: "512MB"
2514
+ })
2515
+ .https.onCall(async (data) => {
2516
+ if (!BANDADA_GROUP_ID)
2517
+ throw new Error("BANDADA_GROUP_ID is not defined in .env");
2518
+ const { proof, publicSignals } = data;
2519
+ const isCorrect = snarkjs.groth16.verify(VKEY_DATA, publicSignals, proof);
2520
+ if (!isCorrect)
2521
+ return {
2522
+ valid: false,
2523
+ message: "Invalid proof",
2524
+ token: ""
2525
+ };
2526
+ const commitment = data.publicSignals[1];
2527
+ const isMember = await bandadaApi.isGroupMember(BANDADA_GROUP_ID, commitment);
2528
+ if (!isMember)
2529
+ return {
2530
+ valid: false,
2531
+ message: "Not a member of the group",
2532
+ token: ""
2533
+ };
2534
+ const auth$1 = auth.getAuth();
2535
+ try {
2536
+ await admin.auth().createUser({
2537
+ uid: commitment
2538
+ });
2539
+ }
2540
+ catch (error) {
2541
+ // if user already exist then just pass
2542
+ if (error.code !== "auth/uid-already-exists") {
2543
+ throw new Error(error);
2544
+ }
2545
+ }
2546
+ const token = await auth$1.createCustomToken(commitment);
2547
+ return {
2548
+ valid: true,
2549
+ message: "Valid proof and group member",
2550
+ token
2551
+ };
2552
+ });
2553
+
2410
2554
  dotenv.config();
2411
2555
  /**
2412
2556
  * Check and remove the current contributor if it doesn't complete the contribution on the specified amount of time.
@@ -2608,6 +2752,7 @@ const resumeContributionAfterTimeoutExpiration = functions__namespace
2608
2752
 
2609
2753
  admin.initializeApp();
2610
2754
 
2755
+ exports.bandadaValidateProof = bandadaValidateProof;
2611
2756
  exports.checkAndPrepareCoordinatorForFinalization = checkAndPrepareCoordinatorForFinalization;
2612
2757
  exports.checkAndRemoveBlockingContributor = checkAndRemoveBlockingContributor;
2613
2758
  exports.checkIfObjectExist = checkIfObjectExist;
@@ -28,7 +28,9 @@ import { EC2Client } from '@aws-sdk/client-ec2';
28
28
  import * as functionsV1 from 'firebase-functions/v1';
29
29
  import * as functionsV2 from 'firebase-functions/v2';
30
30
  import { Timer } from 'timer-node';
31
- import { zKey } from 'snarkjs';
31
+ import { zKey, groth16 } from 'snarkjs';
32
+ import { ApiSdk } from '@bandada/api-sdk';
33
+ import { getAuth } from 'firebase-admin/auth';
32
34
 
33
35
  /**
34
36
  * Log levels.
@@ -533,7 +535,7 @@ const registerAuthUser = functions
533
535
  email === process.env.CUSTOM_CLAIMS_COORDINATOR_EMAIL_ADDRESS_OR_DOMAIN)) {
534
536
  const auth = admin.auth();
535
537
  // if provider == github.com let's use our functions to check the user's reputation
536
- if (user.providerData[0].providerId === "github.com") {
538
+ if (user.providerData.length > 0 && user.providerData[0].providerId === "github.com") {
537
539
  const vars = getGitHubVariables();
538
540
  // this return true or false
539
541
  try {
@@ -565,7 +567,7 @@ const registerAuthUser = functions
565
567
  encodedDisplayName,
566
568
  // Metadata.
567
569
  creationTime,
568
- lastSignInTime,
570
+ lastSignInTime: lastSignInTime || creationTime,
569
571
  // Optional.
570
572
  email: email || "",
571
573
  emailVerified: emailVerified || false,
@@ -2384,6 +2386,148 @@ const completeMultiPartUpload = functions
2384
2386
  }
2385
2387
  });
2386
2388
 
2389
+ const VKEY_DATA = {
2390
+ protocol: "groth16",
2391
+ curve: "bn128",
2392
+ nPublic: 3,
2393
+ vk_alpha_1: [
2394
+ "20491192805390485299153009773594534940189261866228447918068658471970481763042",
2395
+ "9383485363053290200918347156157836566562967994039712273449902621266178545958",
2396
+ "1"
2397
+ ],
2398
+ vk_beta_2: [
2399
+ [
2400
+ "6375614351688725206403948262868962793625744043794305715222011528459656738731",
2401
+ "4252822878758300859123897981450591353533073413197771768651442665752259397132"
2402
+ ],
2403
+ [
2404
+ "10505242626370262277552901082094356697409835680220590971873171140371331206856",
2405
+ "21847035105528745403288232691147584728191162732299865338377159692350059136679"
2406
+ ],
2407
+ ["1", "0"]
2408
+ ],
2409
+ vk_gamma_2: [
2410
+ [
2411
+ "10857046999023057135944570762232829481370756359578518086990519993285655852781",
2412
+ "11559732032986387107991004021392285783925812861821192530917403151452391805634"
2413
+ ],
2414
+ [
2415
+ "8495653923123431417604973247489272438418190587263600148770280649306958101930",
2416
+ "4082367875863433681332203403145435568316851327593401208105741076214120093531"
2417
+ ],
2418
+ ["1", "0"]
2419
+ ],
2420
+ vk_delta_2: [
2421
+ [
2422
+ "3697618915467790705869942236922063775466274665053173890632463796679068973252",
2423
+ "14948341351907992175709156460547989243732741534604949238422596319735704165658"
2424
+ ],
2425
+ [
2426
+ "3028459181652799888716942141752307629938889957960373621898607910203491239368",
2427
+ "11380736494786911280692284374675752681598754560757720296073023058533044108340"
2428
+ ],
2429
+ ["1", "0"]
2430
+ ],
2431
+ vk_alphabeta_12: [
2432
+ [
2433
+ [
2434
+ "2029413683389138792403550203267699914886160938906632433982220835551125967885",
2435
+ "21072700047562757817161031222997517981543347628379360635925549008442030252106"
2436
+ ],
2437
+ [
2438
+ "5940354580057074848093997050200682056184807770593307860589430076672439820312",
2439
+ "12156638873931618554171829126792193045421052652279363021382169897324752428276"
2440
+ ],
2441
+ [
2442
+ "7898200236362823042373859371574133993780991612861777490112507062703164551277",
2443
+ "7074218545237549455313236346927434013100842096812539264420499035217050630853"
2444
+ ]
2445
+ ],
2446
+ [
2447
+ [
2448
+ "7077479683546002997211712695946002074877511277312570035766170199895071832130",
2449
+ "10093483419865920389913245021038182291233451549023025229112148274109565435465"
2450
+ ],
2451
+ [
2452
+ "4595479056700221319381530156280926371456704509942304414423590385166031118820",
2453
+ "19831328484489333784475432780421641293929726139240675179672856274388269393268"
2454
+ ],
2455
+ [
2456
+ "11934129596455521040620786944827826205713621633706285934057045369193958244500",
2457
+ "8037395052364110730298837004334506829870972346962140206007064471173334027475"
2458
+ ]
2459
+ ]
2460
+ ],
2461
+ IC: [
2462
+ [
2463
+ "12951059800758687233303204819298121944551181861362200875212570257618182506154",
2464
+ "5751958719396509176593242305268064754837298673622815112953832050159760501392",
2465
+ "1"
2466
+ ],
2467
+ [
2468
+ "9561588427935871983444704959674198910445823619407211599507208879011862515257",
2469
+ "14576201570478094842467636169770180675293504492823217349086195663150934064643",
2470
+ "1"
2471
+ ],
2472
+ [
2473
+ "4811967233483727873912563574622036989372099129165459921963463310078093941559",
2474
+ "1874883809855039536107616044787862082553628089593740724610117059083415551067",
2475
+ "1"
2476
+ ],
2477
+ [
2478
+ "12252730267779308452229639835051322390696643456253768618882001876621526827161",
2479
+ "7899194018737016222260328309937800777948677569409898603827268776967707173231",
2480
+ "1"
2481
+ ]
2482
+ ]
2483
+ };
2484
+ dotenv.config();
2485
+ const { BANDADA_API_URL, BANDADA_GROUP_ID } = process.env;
2486
+ const bandadaApi = new ApiSdk(BANDADA_API_URL);
2487
+ const bandadaValidateProof = functions
2488
+ .region("europe-west1")
2489
+ .runWith({
2490
+ memory: "512MB"
2491
+ })
2492
+ .https.onCall(async (data) => {
2493
+ if (!BANDADA_GROUP_ID)
2494
+ throw new Error("BANDADA_GROUP_ID is not defined in .env");
2495
+ const { proof, publicSignals } = data;
2496
+ const isCorrect = groth16.verify(VKEY_DATA, publicSignals, proof);
2497
+ if (!isCorrect)
2498
+ return {
2499
+ valid: false,
2500
+ message: "Invalid proof",
2501
+ token: ""
2502
+ };
2503
+ const commitment = data.publicSignals[1];
2504
+ const isMember = await bandadaApi.isGroupMember(BANDADA_GROUP_ID, commitment);
2505
+ if (!isMember)
2506
+ return {
2507
+ valid: false,
2508
+ message: "Not a member of the group",
2509
+ token: ""
2510
+ };
2511
+ const auth = getAuth();
2512
+ try {
2513
+ await admin.auth().createUser({
2514
+ uid: commitment
2515
+ });
2516
+ }
2517
+ catch (error) {
2518
+ // if user already exist then just pass
2519
+ if (error.code !== "auth/uid-already-exists") {
2520
+ throw new Error(error);
2521
+ }
2522
+ }
2523
+ const token = await auth.createCustomToken(commitment);
2524
+ return {
2525
+ valid: true,
2526
+ message: "Valid proof and group member",
2527
+ token
2528
+ };
2529
+ });
2530
+
2387
2531
  dotenv.config();
2388
2532
  /**
2389
2533
  * Check and remove the current contributor if it doesn't complete the contribution on the specified amount of time.
@@ -2585,4 +2729,4 @@ const resumeContributionAfterTimeoutExpiration = functions
2585
2729
 
2586
2730
  admin.initializeApp();
2587
2731
 
2588
- export { checkAndPrepareCoordinatorForFinalization, checkAndRemoveBlockingContributor, checkIfObjectExist, checkParticipantForCeremony, completeMultiPartUpload, coordinateCeremonyParticipant, createBucket, finalizeCeremony, finalizeCircuit, generateGetObjectPreSignedUrl, generatePreSignedUrlsParts, initEmptyWaitingQueueForCircuit, permanentlyStoreCurrentContributionTimeAndHash, processSignUpWithCustomClaims, progressToNextCircuitForContribution, progressToNextContributionStep, refreshParticipantAfterContributionVerification, registerAuthUser, resumeContributionAfterTimeoutExpiration, setupCeremony, startCeremony, startMultiPartUpload, stopCeremony, temporaryStoreCurrentContributionMultiPartUploadId, temporaryStoreCurrentContributionUploadedChunkData, verifycontribution };
2732
+ export { bandadaValidateProof, checkAndPrepareCoordinatorForFinalization, checkAndRemoveBlockingContributor, checkIfObjectExist, checkParticipantForCeremony, completeMultiPartUpload, coordinateCeremonyParticipant, createBucket, finalizeCeremony, finalizeCircuit, generateGetObjectPreSignedUrl, generatePreSignedUrlsParts, initEmptyWaitingQueueForCircuit, permanentlyStoreCurrentContributionTimeAndHash, processSignUpWithCustomClaims, progressToNextCircuitForContribution, progressToNextContributionStep, refreshParticipantAfterContributionVerification, registerAuthUser, resumeContributionAfterTimeoutExpiration, setupCeremony, startCeremony, startMultiPartUpload, stopCeremony, temporaryStoreCurrentContributionMultiPartUploadId, temporaryStoreCurrentContributionUploadedChunkData, verifycontribution };
@@ -0,0 +1,4 @@
1
+ import * as functions from "firebase-functions";
2
+ export declare const bandadaValidateProof: functions.HttpsFunction & functions.Runnable<any>;
3
+ export default bandadaValidateProof;
4
+ //# sourceMappingURL=bandada.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bandada.d.ts","sourceRoot":"","sources":["../../../src/functions/bandada.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AA8G/C,eAAO,MAAM,oBAAoB,mDA0C3B,CAAA;AAEN,eAAe,oBAAoB,CAAA"}
@@ -3,5 +3,6 @@ export { startCeremony, stopCeremony, setupCeremony, initEmptyWaitingQueueForCir
3
3
  export { checkParticipantForCeremony, progressToNextContributionStep, permanentlyStoreCurrentContributionTimeAndHash, temporaryStoreCurrentContributionMultiPartUploadId, temporaryStoreCurrentContributionUploadedChunkData, progressToNextCircuitForContribution, checkAndPrepareCoordinatorForFinalization } from "./participant";
4
4
  export { coordinateCeremonyParticipant, verifycontribution, refreshParticipantAfterContributionVerification, finalizeCircuit } from "./circuit";
5
5
  export { createBucket, checkIfObjectExist, generateGetObjectPreSignedUrl, startMultiPartUpload, generatePreSignedUrlsParts, completeMultiPartUpload } from "./storage";
6
+ export { bandadaValidateProof } from "./bandada";
6
7
  export { checkAndRemoveBlockingContributor, resumeContributionAfterTimeoutExpiration } from "./timeout";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/functions/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EACH,aAAa,EACb,YAAY,EACZ,aAAa,EACb,+BAA+B,EAC/B,gBAAgB,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACH,2BAA2B,EAC3B,8BAA8B,EAC9B,8CAA8C,EAC9C,kDAAkD,EAClD,kDAAkD,EAClD,oCAAoC,EACpC,yCAAyC,EAC5C,MAAM,eAAe,CAAA;AACtB,OAAO,EACH,6BAA6B,EAC7B,kBAAkB,EAClB,+CAA+C,EAC/C,eAAe,EAClB,MAAM,WAAW,CAAA;AAClB,OAAO,EACH,YAAY,EACZ,kBAAkB,EAClB,6BAA6B,EAC7B,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EAC1B,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,iCAAiC,EAAE,wCAAwC,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/functions/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EACH,aAAa,EACb,YAAY,EACZ,aAAa,EACb,+BAA+B,EAC/B,gBAAgB,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACH,2BAA2B,EAC3B,8BAA8B,EAC9B,8CAA8C,EAC9C,kDAAkD,EAClD,kDAAkD,EAClD,oCAAoC,EACpC,yCAAyC,EAC5C,MAAM,eAAe,CAAA;AACtB,OAAO,EACH,6BAA6B,EAC7B,kBAAkB,EAClB,+CAA+C,EAC/C,eAAe,EAClB,MAAM,WAAW,CAAA;AAClB,OAAO,EACH,YAAY,EACZ,kBAAkB,EAClB,6BAA6B,EAC7B,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EAC1B,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EAAE,iCAAiC,EAAE,wCAAwC,EAAE,MAAM,WAAW,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { CeremonyInputData, CircuitDocument, ETagWithPartNumber } from "@devtion/actions";
2
+ import type { Groth16Proof, PublicSignals } from "snarkjs";
2
3
  /**
3
4
  * Group all the necessary data needed for running the `setupCeremony` cloud function.
4
5
  * @typedef {Object} SetupCeremonyData
@@ -127,4 +128,28 @@ export type FinalizeCircuitData = {
127
128
  bucketName: string;
128
129
  beacon: string;
129
130
  };
131
+ /**
132
+ * Group all the necessary data needed for running the `bandadaValidateProof` cloud function.
133
+ * @typedef {Object} BandadaValidateProof
134
+ * @property {string} merkleTreeRoot - the merkle tree root of the group.
135
+ * @property {string} nullifierHash - the nullifier hash of the member.
136
+ * @property {string} externalNullifier - the external nullifier of the member.
137
+ * @property {PackedProof} proof - the packed proof generated on the client.
138
+ */
139
+ export type BandadaValidateProof = {
140
+ proof: Groth16Proof;
141
+ publicSignals: PublicSignals;
142
+ };
143
+ /**
144
+ * Define the return object of the function that verifies the Bandada membership and proof.
145
+ * @typedef {Object} VerifiedBandadaResponse
146
+ * @property {boolean} valid - true if the proof is valid and the user is a member of the group; otherwise false.
147
+ * @property {string} message - a message describing the result of the verification.
148
+ * @property {string} token - the custom access token.
149
+ */
150
+ export type VerifiedBandadaResponse = {
151
+ valid: boolean;
152
+ message: string;
153
+ token: string;
154
+ };
130
155
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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"}
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;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE1D;;;;;;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;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAC/B,KAAK,EAAE,YAAY,CAAA;IACnB,aAAa,EAAE,aAAa,CAAA;CAC/B,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAClC,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CAChB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devtion/backend",
3
- "version": "0.0.0-56ecf35",
3
+ "version": "0.0.0-57a8ab9",
4
4
  "description": "MPC Phase 2 backend for Firebase services management",
5
5
  "repository": "git@github.com:privacy-scaling-explorations/p0tion.git",
6
6
  "homepage": "https://github.com/privacy-scaling-explorations/p0tion",
@@ -67,6 +67,7 @@
67
67
  "@aws-sdk/client-ssm": "^3.357.0",
68
68
  "@aws-sdk/middleware-endpoint": "^3.329.0",
69
69
  "@aws-sdk/s3-request-presigner": "^3.329.0",
70
+ "@bandada/api-sdk": "^1.0.0-beta.1",
70
71
  "@devtion/actions": "latest",
71
72
  "blakejs": "^1.2.1",
72
73
  "dotenv": "^16.0.3",
@@ -76,7 +77,7 @@
76
77
  "html-entities": "^2.3.3",
77
78
  "rimraf": "^5.0.0",
78
79
  "rollup": "^3.21.6",
79
- "snarkjs": "^0.6.11",
80
+ "snarkjs": "0.7.3",
80
81
  "solc": "^0.8.19",
81
82
  "timer-node": "^5.0.7",
82
83
  "uuid": "^9.0.0",
@@ -85,5 +86,5 @@
85
86
  "publishConfig": {
86
87
  "access": "public"
87
88
  },
88
- "gitHead": "7d72963a1027f3e86cecf40d3255f04cc74e4826"
89
+ "gitHead": "6bddf60f1121786c19ad4437e0448de4c859b829"
89
90
  }
@@ -0,0 +1,156 @@
1
+ import dotenv from "dotenv"
2
+ import * as functions from "firebase-functions"
3
+ import { ApiSdk } from "@bandada/api-sdk"
4
+ import { groth16 } from "snarkjs"
5
+ import { getAuth } from "firebase-admin/auth"
6
+ import { BandadaValidateProof, VerifiedBandadaResponse } from "../types/index"
7
+
8
+ import admin from "firebase-admin"
9
+
10
+ const VKEY_DATA = {
11
+ protocol: "groth16",
12
+ curve: "bn128",
13
+ nPublic: 3,
14
+ vk_alpha_1: [
15
+ "20491192805390485299153009773594534940189261866228447918068658471970481763042",
16
+ "9383485363053290200918347156157836566562967994039712273449902621266178545958",
17
+ "1"
18
+ ],
19
+ vk_beta_2: [
20
+ [
21
+ "6375614351688725206403948262868962793625744043794305715222011528459656738731",
22
+ "4252822878758300859123897981450591353533073413197771768651442665752259397132"
23
+ ],
24
+ [
25
+ "10505242626370262277552901082094356697409835680220590971873171140371331206856",
26
+ "21847035105528745403288232691147584728191162732299865338377159692350059136679"
27
+ ],
28
+ ["1", "0"]
29
+ ],
30
+ vk_gamma_2: [
31
+ [
32
+ "10857046999023057135944570762232829481370756359578518086990519993285655852781",
33
+ "11559732032986387107991004021392285783925812861821192530917403151452391805634"
34
+ ],
35
+ [
36
+ "8495653923123431417604973247489272438418190587263600148770280649306958101930",
37
+ "4082367875863433681332203403145435568316851327593401208105741076214120093531"
38
+ ],
39
+ ["1", "0"]
40
+ ],
41
+ vk_delta_2: [
42
+ [
43
+ "3697618915467790705869942236922063775466274665053173890632463796679068973252",
44
+ "14948341351907992175709156460547989243732741534604949238422596319735704165658"
45
+ ],
46
+ [
47
+ "3028459181652799888716942141752307629938889957960373621898607910203491239368",
48
+ "11380736494786911280692284374675752681598754560757720296073023058533044108340"
49
+ ],
50
+ ["1", "0"]
51
+ ],
52
+ vk_alphabeta_12: [
53
+ [
54
+ [
55
+ "2029413683389138792403550203267699914886160938906632433982220835551125967885",
56
+ "21072700047562757817161031222997517981543347628379360635925549008442030252106"
57
+ ],
58
+ [
59
+ "5940354580057074848093997050200682056184807770593307860589430076672439820312",
60
+ "12156638873931618554171829126792193045421052652279363021382169897324752428276"
61
+ ],
62
+ [
63
+ "7898200236362823042373859371574133993780991612861777490112507062703164551277",
64
+ "7074218545237549455313236346927434013100842096812539264420499035217050630853"
65
+ ]
66
+ ],
67
+ [
68
+ [
69
+ "7077479683546002997211712695946002074877511277312570035766170199895071832130",
70
+ "10093483419865920389913245021038182291233451549023025229112148274109565435465"
71
+ ],
72
+ [
73
+ "4595479056700221319381530156280926371456704509942304414423590385166031118820",
74
+ "19831328484489333784475432780421641293929726139240675179672856274388269393268"
75
+ ],
76
+ [
77
+ "11934129596455521040620786944827826205713621633706285934057045369193958244500",
78
+ "8037395052364110730298837004334506829870972346962140206007064471173334027475"
79
+ ]
80
+ ]
81
+ ],
82
+ IC: [
83
+ [
84
+ "12951059800758687233303204819298121944551181861362200875212570257618182506154",
85
+ "5751958719396509176593242305268064754837298673622815112953832050159760501392",
86
+ "1"
87
+ ],
88
+ [
89
+ "9561588427935871983444704959674198910445823619407211599507208879011862515257",
90
+ "14576201570478094842467636169770180675293504492823217349086195663150934064643",
91
+ "1"
92
+ ],
93
+ [
94
+ "4811967233483727873912563574622036989372099129165459921963463310078093941559",
95
+ "1874883809855039536107616044787862082553628089593740724610117059083415551067",
96
+ "1"
97
+ ],
98
+ [
99
+ "12252730267779308452229639835051322390696643456253768618882001876621526827161",
100
+ "7899194018737016222260328309937800777948677569409898603827268776967707173231",
101
+ "1"
102
+ ]
103
+ ]
104
+ }
105
+
106
+ dotenv.config()
107
+
108
+ const { BANDADA_API_URL, BANDADA_GROUP_ID } = process.env
109
+
110
+ const bandadaApi = new ApiSdk(BANDADA_API_URL)
111
+
112
+ export const bandadaValidateProof = functions
113
+ .region("europe-west1")
114
+ .runWith({
115
+ memory: "512MB"
116
+ })
117
+ .https.onCall(async (data: BandadaValidateProof): Promise<VerifiedBandadaResponse> => {
118
+ if (!BANDADA_GROUP_ID) throw new Error("BANDADA_GROUP_ID is not defined in .env")
119
+
120
+ const { proof, publicSignals } = data
121
+ const isCorrect = groth16.verify(VKEY_DATA, publicSignals, proof)
122
+ if (!isCorrect)
123
+ return {
124
+ valid: false,
125
+ message: "Invalid proof",
126
+ token: ""
127
+ }
128
+
129
+ const commitment = data.publicSignals[1]
130
+ const isMember = await bandadaApi.isGroupMember(BANDADA_GROUP_ID, commitment)
131
+ if (!isMember)
132
+ return {
133
+ valid: false,
134
+ message: "Not a member of the group",
135
+ token: ""
136
+ }
137
+ const auth = getAuth()
138
+ try {
139
+ await admin.auth().createUser({
140
+ uid: commitment
141
+ })
142
+ } catch (error: any) {
143
+ // if user already exist then just pass
144
+ if (error.code !== "auth/uid-already-exists") {
145
+ throw new Error(error)
146
+ }
147
+ }
148
+ const token = await auth.createCustomToken(commitment)
149
+ return {
150
+ valid: true,
151
+ message: "Valid proof and group member",
152
+ token
153
+ }
154
+ })
155
+
156
+ export default bandadaValidateProof
@@ -31,6 +31,7 @@ export {
31
31
  generatePreSignedUrlsParts,
32
32
  completeMultiPartUpload
33
33
  } from "./storage"
34
+ export { bandadaValidateProof } from "./bandada"
34
35
  export { checkAndRemoveBlockingContributor, resumeContributionAfterTimeoutExpiration } from "./timeout"
35
36
 
36
37
  admin.initializeApp()
@@ -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
@@ -112,7 +112,7 @@ export const registerAuthUser = functions
112
112
  encodedDisplayName,
113
113
  // Metadata.
114
114
  creationTime,
115
- lastSignInTime,
115
+ lastSignInTime: lastSignInTime || creationTime,
116
116
  // Optional.
117
117
  email: email || "",
118
118
  emailVerified: emailVerified || false,
@@ -0,0 +1 @@
1
+ declare module "@bandada/api-sdk"
@@ -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,29 @@ 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
+ }