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

Code cleanup #8764

Merged
merged 7 commits into from
Oct 12, 2021
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
10 changes: 6 additions & 4 deletions packages/attestation-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ You can use the following environment variables to configure the attestation ser
- `ATTESTATION_SIGNER_ADDRESS` - The address of the key with which attestations should be signed.
- `SMS_PROVIDERS` - A comma-separated list of providers you want to configure, we currently support:

`nexmo`
`vonage` (previously `nexmo`)

- `NEXMO_KEY` - The API key to the Nexmo API
- `NEXMO_SECRET` - The API secret to the Nexmo API
- `NEXMO_BLACKLIST` - A comma-sperated list of country codes you do not want to serve
- `VONAGE_KEY` - The API key to the Vonage API
- `VONAGE_SECRET` - The API secret to the Vonage API
- `VONAGE_BLACKLIST` - A comma-sperated list of country codes you do not want to serve

`twilio`

Expand Down Expand Up @@ -55,6 +55,8 @@ Here is a list of the error codes and messages returned by the Attestation Servi

- `Mismatching issuer, I am ${address}` - The attestation request references an issuer address that does not match that of the AS that actually received the request.
- `NO_INCOMPLETE_ATTESTATION_FOUND_ERROR / 'No incomplete attestation found'` - The Attestations contract has no record that this AS was randomly assigned as an issuer for the given account/identifier pair.
- `I am not an authorized issuer for this account` - The AS is not authorized to issue a PhoneNumberType VerifiableCredential for this user. This means the Attestations contract has no record that this AS was randomly assigned as an issuer for the given account/identifier pair.
- `Can't issue a credential for an incomplete attestation` - The user has requested a PhoneNumberType VerifiableCredential from an issuer with whom the user has not completed a phone number ownership attestation.
- `ATTESTATION_ERROR / 'Valid attestation could not be provided'` - A call to validateAttestationCode in the Attestations contract has failed. This method checks that (1) there is a non-expired incomplete attestation assigned to the issuer whose signature constitutes the given attestation code.
- `'Invalid securityCodePrefix'` - A security code prefix with an incorrect length was provided in the attestation request.
- `'Invalid smsRetrieverAppSig'` - The provided smsRetrieverAppSig does not match the regex `'^[\\w+]{5,12}$'`
Expand Down
13 changes: 5 additions & 8 deletions packages/attestation-service/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@ if (process.env.CONFIG) {
dotenv.config({ path: process.env.CONFIG })
}

const checkEnv = (name: string) =>
(process.env[name] === undefined || process.env[name] === '') &&
(process.env[name.toLowerCase()] === undefined || process.env[name.toLowerCase()] === '')
const _fetchEnv = (name: string) => process.env[name] || process.env[name.toLowerCase()]

export function fetchEnv(name: string): string {
if (checkEnv(name)) {
const env = _fetchEnv(name)
if (!env) {
console.error(`ENV var '${name}' was not defined`)
throw new Error(`ENV var '${name}' was not defined`)
}
return (process.env[name] || process.env[name.toLowerCase()]) as string
return env
}

export function fetchEnvOrDefault(name: string, defaultValue: string): string {
return checkEnv(name)
? defaultValue
: ((process.env[name] || process.env[name.toLowerCase()]) as string)
return _fetchEnv(name) || defaultValue
}

export function isYes(value: string) {
Expand Down
17 changes: 7 additions & 10 deletions packages/attestation-service/src/lookup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,29 @@ export function configuredLookupProviders() {

export const issueAttestationPhoneNumberTypeCredential = async (
attestation: AttestationModel,
logger: any
logger: Logger
) => {
try {
const phoneNumberTypeProvider = await lookupPhoneNumber(attestation, logger)
const attestationSignerAddress = getAttestationSignerAddress().toLowerCase()

const credential = VerifiableCredentialUtils.getPhoneNumberTypeJSONLD(
attestation.phoneNumberType,
attestation.account.toLowerCase(),
getAttestationSignerAddress().toLowerCase(),
attestationSignerAddress,
attestation.identifier,
phoneNumberTypeProvider
)

const proofOptions = VerifiableCredentialUtils.getProofOptions(
getAttestationSignerAddress().toLowerCase()
)
const proofOptions = VerifiableCredentialUtils.getProofOptions(attestationSignerAddress)

return await VerifiableCredentialUtils.issueCredential(
credential,
proofOptions,
async (signInput) =>
useKit(async (kit) =>
SignatureUtils.serializeSignature(
await kit.connection.signTypedData(
getAttestationSignerAddress().toLowerCase(),
signInput
)
await kit.connection.signTypedData(attestationSignerAddress, signInput)
)
)
)
Expand All @@ -106,7 +103,7 @@ async function lookupPhoneNumber(
logger.info(
{
provider: provider.type,
phoneNumber: obfuscateNumber(attestation.phoneNumber),
obfuscatedPhoneNumber: obfuscateNumber(attestation.phoneNumber),
},
'Lookup phoneNumber'
)
Expand Down
1 change: 1 addition & 0 deletions packages/attestation-service/src/lookup/vonage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class VonageLookupProvider extends LookupProvider {
this.client = new Vonage({
apiKey,
apiSecret,
applicationId,
})
} else {
this.client = new Vonage({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class VerifiableCredentialHandler {
)
}

async validateRequest(issuer: string, issuers: string[]) {
validateRequest(issuer: string, issuers: string[]) {
const address = getAccountAddress()
if (!eqAddress(address, issuer)) {
throw new ErrorWithResponse(`Mismatching issuer, I am ${address}`, 422)
Expand All @@ -36,15 +36,13 @@ export class VerifiableCredentialHandler {
async doCredential(account: string, issuer: string, identifier: string, logger: Logger) {
const attestations = await useKit((kit) => kit.contracts.getAttestations())

const issuers = await attestations.getAttestationIssuers(identifier, account)

// Checks if the attestation service is an authorized issuer
await this.validateRequest(issuer, issuers)
this.validateRequest(issuer, await attestations.getAttestationIssuers(identifier, account))

const state = await attestations.getAttestationState(identifier, account, issuer)

// Checks if the attestation is marked as completed
if (state.attestationState === AttestationState.Complete) {
if (state.attestationState !== AttestationState.Complete) {
alecps marked this conversation as resolved.
Show resolved Hide resolved
throw new ErrorWithResponse(`Can't issue a credential for an incomplete attestation`, 422)
}

Expand All @@ -54,11 +52,11 @@ export class VerifiableCredentialHandler {
account,
})

if (attestation) {
return JSON.parse(await issueAttestationPhoneNumberTypeCredential(attestation, logger))
} else {
throw new Error('Unable to find attestation')
if (!attestation) {
throw new Error('Unable to find attestation in db')
}

return JSON.parse(await issueAttestationPhoneNumberTypeCredential(attestation, logger))
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/attestation-service/src/sms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export async function startSendSms(
)
attestation.credentials = `[${verifiableCredential}]`
} catch (e) {
logger.error({ e: e.message })
logger.error({ e: e.message }, 'Error issuing phone-number-type credential')
}

if (!countryCode) {
Expand Down
40 changes: 16 additions & 24 deletions packages/attestation-service/src/sms/vonage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,33 @@ const phoneUtil = PhoneNumberUtil.getInstance()

export class VonageSmsProvider extends SmsProvider {
static fromEnv() {
const _unsupportedRegionCodes = readUnsupportedRegionsFromEnv(
'VONAGE_UNSUPPORTED_REGIONS',
'VONAGE_BLACKLIST',
'NEXMO_UNSUPPORTED_REGIONS',
'NEXMO_BLACKLIST'
)
const _balanceMetric = isYes(
fetchEnvOrDefault(
'VONAGE_ACCOUNT_BALANCE_METRIC',
fetchEnvOrDefault('NEXMO_ACCOUNT_BALANCE_METRIC', '')
)
)
try {
return new VonageSmsProvider(
fetchEnv('VONAGE_KEY'),
alecps marked this conversation as resolved.
Show resolved Hide resolved
fetchEnv('VONAGE_SECRET'),
fetchEnvOrDefault('VONAGE_APPLICATION', ''),
readUnsupportedRegionsFromEnv(
'VONAGE_UNSUPPORTED_REGIONS',
'VONAGE_BLACKLIST',
'NEXMO_UNSUPPORTED_REGIONS',
'NEXMO_BLACKLIST'
),
isYes(
fetchEnvOrDefault(
'VONAGE_ACCOUNT_BALANCE_METRIC',
fetchEnvOrDefault('NEXMO_ACCOUNT_BALANCE_METRIC', '')
)
)
_unsupportedRegionCodes,
_balanceMetric
)
} catch (e) {
return new VonageSmsProvider(
fetchEnv('NEXMO_KEY'),
fetchEnv('NEXMO_SECRET'),
fetchEnvOrDefault('NEXMO_APPLICATION', ''),
readUnsupportedRegionsFromEnv(
'VONAGE_UNSUPPORTED_REGIONS',
'VONAGE_BLACKLIST',
'NEXMO_UNSUPPORTED_REGIONS',
'NEXMO_BLACKLIST'
),
isYes(
fetchEnvOrDefault(
'VONAGE_ACCOUNT_BALANCE_METRIC',
fetchEnvOrDefault('NEXMO_ACCOUNT_BALANCE_METRIC', '')
)
)
_unsupportedRegionCodes,
_balanceMetric
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/utils/src/verifiableCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { completeIssueCredential, prepareIssueCredential, verifyCredential } fro
* @param phoneNumberTypeProvider The lookup provider of the phone number type
* @param subject Subject of the verifiable credential, usually a Valora user
* @param issuer Address of whom is issuing this credential, usually getAttestationSignerAddress()
* @param identifier Transaction identifier
* @param identifier ODIS identifier for the phone number
*/
export const getPhoneNumberTypeJSONLD = (
phoneNumberType: string,
Expand Down