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

Bugfix release #155

Merged
merged 13 commits into from
Nov 8, 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
15 changes: 12 additions & 3 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,19 @@ export const check_if_code_is_expected = ( code_to_check, expected_codes ) => {

export async function extract_redirect_url ( response ) {

cy.log( `Url from which to extract challenge: `, response )
// strinified response
console.log( `Response data: `, JSON.stringify( response ) )
cy.log( `Response object from which to extract challenge (can be printed to browser console): `, response )
const { redirects } = response

// If there are no redirects, something weird happens that we need to debug
if( !redirects?.length ) {
cy.log( `No redirects found, full response body (status ${ response.status }): `, response.body )
cy.log( `There were ${ response?.allRequestResponses?.length } responses to the request:` )
response?.allRequestResponses?.forEach( unique_res => {
cy.log( `Status ${ unique_res[ 'Response Status' ] } from ${ unique_res[ 'Request URL' ] }`, unique_res[ 'Response Body' ] )
} )
return null
}

const [ redirect_url ] = redirects
cy.log( `Redirect: `, redirect_url )
return redirect_url
Expand Down
12 changes: 6 additions & 6 deletions functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ exports.getEventDataFromCode = v1_oncall( getEventDataFromCode )
exports.check_code_status = v1_oncall( check_code_status )

// Refresh all codes ( trigger from frontend on page mount of EventView )
exports.requestManualCodeRefresh = v1_oncall( [ 'high_memory', 'long_timeout' ], refresh_unknown_and_unscanned_codes )
exports.requestManualCodeRefresh = v1_oncall( [ 'memory_512MiB', 'long_timeout' ], refresh_unknown_and_unscanned_codes )

// Allow frontend to trigger updates for scanned codes, ( triggers on a periodic interval from EventView ), is lighter than requestManualCodeRefresh as it checks only scanned and claimed == true codes
exports.refreshScannedCodesStatuses = v1_oncall( [ 'high_memory', 'long_timeout' ], refreshScannedCodesStatuses )
exports.refreshScannedCodesStatuses = v1_oncall( [ 'memory_512MiB', 'long_timeout' ], refreshScannedCodesStatuses )

// Directly mint a code to an address
const { mint_code_to_address } = require( './modules/minting' )
exports.mint_code_to_address = v2_oncall( [ 'high_memory', 'long_timeout' ], mint_code_to_address )
exports.mint_code_to_address = v2_oncall( [ 'memory_512MiB', 'long_timeout' ], mint_code_to_address )

// Let admins recalculate available codes
const { recalculate_available_codes_admin } = require( './modules/codes' )
Expand All @@ -45,7 +45,7 @@ exports.recalculate_available_codes = v2_oncall( recalculate_available_codes_adm
// ///////////////////////////////

const { registerEvent, deleteEvent, getUniqueOrganiserEmails } = require( './modules/events' )
exports.registerEvent = v1_oncall( [ 'high_memory', 'long_timeout' ], registerEvent )
exports.registerEvent = v1_oncall( [ 'memory_1GiB', 'long_timeout' ], registerEvent )
exports.deleteEvent = v1_oncall( deleteEvent )

// Email export to update event organisers
Expand All @@ -55,7 +55,7 @@ exports.getUniqueOrganiserEmails = v1_oncall( getUniqueOrganiserEmails )
// QR Middleware API
// ///////////////////////////////
const claimMiddleware = require( './modules/claim' )
exports.claimMiddleware = v2_onrequest( [ 'max_concurrency', 'keep_warm', 'memory' ], claimMiddleware )
exports.claimMiddleware = v2_onrequest( [ 'max_concurrency', 'memory_2GiB' ], claimMiddleware )

/* ///////////////////////////////
// Kiosk generator middleware API
Expand Down Expand Up @@ -84,7 +84,7 @@ exports.updateEventAvailableCodes = functions.firestore.document( `codes/{codeId
// Security
// /////////////////////////////*/
const { validateCallerDevice, validateCallerCaptcha } = require( './modules/security' )
exports.validateCallerDevice = v2_oncall( [ 'high_memory', 'long_timeout', 'keep_warm' ], validateCallerDevice )
exports.validateCallerDevice = v2_oncall( [ 'memory_512MiB', 'long_timeout' ], validateCallerDevice )
exports.validateCallerCaptcha = v1_oncall( validateCallerCaptcha )

// Log kiosk opens
Expand Down
12 changes: 7 additions & 5 deletions functions/modules/minting.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ exports.mint_code_to_address = async ( { data } ) => {
try {

// Function dependencies
const { sanitise_string } = require( './validations' )
const { sanetise_string } = require( '@poap/sane-data' )

// Get the claim code and address to claim to from data property
let { claim_code, challenge_code, address_to_mint_to } = data

// Sanetise data
claim_code = sanitise_string( claim_code )
address_to_mint_to = sanitise_string( address_to_mint_to )
claim_code = sanetise_string( claim_code )
address_to_mint_to = sanetise_string( address_to_mint_to )

// Check if claim code is a mock code
const is_mock = claim_code.includes( 'testing' )
Expand All @@ -36,6 +36,8 @@ exports.mint_code_to_address = async ( { data } ) => {
// Get the claim secret of the mint link
const { call_poap_endpoint } = require( './poap_api' )
const { claimed, secret, error: preclaim_error, message: preclaim_error_message } = await call_poap_endpoint( `/actions/claim-qr`, { qr_hash: claim_code } )

// Handle claim secret errors
if( preclaim_error ) {
log( `Error getting claim secret: `, preclaim_error )
if( preclaim_error_message.includes( "Qr Claim not found" ) ) throw new Error( `Failed to get claim secret: Invalid claim link` )
Expand Down Expand Up @@ -78,12 +80,12 @@ exports.mint_code_to_address = async ( { data } ) => {
}

// Check if the error was due to already being claimed
if( error || message.includes( 'already claimed' ) ) {
if( error && message.includes( 'already claimed' ) ) {
claim_attempts++
continue
}

if( error ) throw new Error( `Failed to mint POAP: ${ error }` )
if( error ) throw new Error( `Failed to mint POAP: ${ message }` )

}

Expand Down
2 changes: 1 addition & 1 deletion functions/modules/poap_api.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Firebase interactors
const { db, dataFromSnap } = require( './firebase' )
const { log, dev } = require( './helpers' )
const { log } = require( './helpers' )

// Secrets
const { POAP_API_KEY, AUTH0_CLIENT_ID, AUTH0_ENDPOINT, AUTH0_CLIENT_SECRET, AUTH0_AUDIENCE } = process.env
Expand Down
2 changes: 1 addition & 1 deletion functions/modules/static_qr_drop.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ exports.create_static_drop = async ( data, context ) => {

exports.update_public_static_drop_data = async function( change, context ) {

const { after, before } = change
const { after } = change
const { drop_id } = context.params

// If this was a deletion, delete public data
Expand Down
68 changes: 0 additions & 68 deletions functions/modules/validations.js

This file was deleted.

11 changes: 11 additions & 0 deletions functions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"main": "index.js",
"dependencies": {
"@poap/sane-data": "^0.0.6",
"@sendgrid/mail": "^7.7.0",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
Expand All @@ -38,4 +39,4 @@
"devDependencies": {
"firebase-tools": "^12.5.3"
}
}
}
11 changes: 11 additions & 0 deletions functions/runtime/on_request_runtimes.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ exports.v1_onrequest = ( runtimes=[], handler ) => {
// If the first parameter was a function, return the undecorated handler
if( typeof runtimes === 'function' ) return functions.https.onRequest( runtimes )

// Check that all runtime keys exist in the v2_runtimes object
const runtime_keys = Object.keys( v1_runtimes )
const invalid_runtime_keys = runtimes.some( runtime_key => !runtime_keys.includes( runtime_key ) )
if( invalid_runtime_keys.length ) throw new Error( `Invalid runtime keys: ${ invalid_runtime_keys }` )

// Config the runtimes for this function
const runtime = runtimes.reduce( ( acc, runtime_key ) => ( { ...acc, ...v1_runtimes[ runtime_key ] } ), {} )
return functions.runWith( runtime ).https.onRequest( handler )
Expand All @@ -32,6 +37,12 @@ exports.v2_onrequest = ( runtimes=[], handler ) => {
// If the first parameter was a function, return the handler as 'protected' firebase oncall
if( typeof runtimes === 'function' ) return onRequest( runtime_basis, runtimes )

// Check that all runtime keys exist in the v2_runtimes object
const runtime_keys = Object.keys( v2_runtimes )
const invalid_runtime_keys = runtimes.some( runtime_key => !runtime_keys.includes( runtime_key ) )
if( invalid_runtime_keys.length ) throw new Error( `Invalid runtime keys: ${ invalid_runtime_keys }` )

const runtime = runtimes.reduce( ( acc, runtime_key ) => ( { ...acc, ...v2_runtimes[ runtime_key ] } ), runtime_basis )

return onRequest( runtime, handler )
}
11 changes: 9 additions & 2 deletions functions/runtime/runtimes_settings.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
// Function to reduce an array of memory declarations to an object of memory declarations
const reduce_memory_declarations = ( acc, memory ) => ( { ...acc, [ `memory_${ memory }` ]: { memory } } )

/**
* See https://firebase.google.com/docs/reference/functions/firebase-functions.runtimeoptions
* @typedef {Object} V1runtimes
* @property {string} high_memory - Allocate high memory to function
* @property {string} long_timeout - Set long timeout to function
* @property {string} keep_warm - Keep function warm
*/
exports.v1_runtimes = {
high_memory: { memory: '4GB' },
// As per https://firebase.google.com/docs/reference/functions/firebase-functions.md#valid_memory_options
...[ "128MB", "256MB", "512MB", "1GB", "2GB", "4GB", "8GB" ].reduce( reduce_memory_declarations, {} ),
long_timeout: { timeoutSeconds: 540 },
keep_warm: { minInstances: 1 },
}

/**
* See https://firebase.google.com/docs/reference/functions/2nd-gen/node/firebase-functions.globaloptions
* @typedef {Object} V2runtimes
* @property {string} protected - Enforce appcheck
* @property {string} long_timeout - Set long timeout to function
Expand All @@ -21,7 +27,8 @@ exports.v1_runtimes = {
exports.v2_runtimes = {
protected: { enforceAppCheck: true },
long_timeout: { timeoutSeconds: 540 },
high_memory: { memory: '4GiB' }, // Note: memory also increases compute power
// As per https://firebase.google.com/docs/reference/functions/2nd-gen/node/firebase-functions.md#memoryoption
...[ "128MiB", "256MiB", "512MiB", "1GiB", "2GiB", "4GiB", "8GiB", "16GiB", "32GiB" ].reduce( reduce_memory_declarations, {} ),
keep_warm: { minInstances: 1 },
max_concurrency: { concurrency: 1000 }
}
Loading