UNPKG

blockstack

Version:

The Blockstack Javascript library for identity and authentication.

336 lines (286 loc) 14.9 kB
'use strict' import blueTest from 'blue-tape' import test from 'tape' import fs from 'fs' import FetchMock from 'fetch-mock' import { validateProofs, containsValidProofStatement, containsValidAddressProofStatement, profileServices } from '../../../lib' import { sampleProfiles, sampleProofs, sampleVerifications, sampleAddressBasedVerifications } from './sampleData' function mockRequests() { const naval = sampleVerifications.naval const larry = sampleVerifications.larry const addressBasedLarry = sampleAddressBasedVerifications.larry FetchMock.get(naval.facebook.url, naval.facebook.body) FetchMock.get(`${naval.github.url}/raw`, naval.github.body) FetchMock.get(naval.twitter.url, naval.twitter.body) FetchMock.get(larry.facebook.url, larry.facebook.body) } function testProofs(profile, username, totalProofs) { mockRequests() blueTest('Profiles', (t) => { return validateProofs(profile, username).then((proofs) => { t.ok(proofs, 'Proofs must have been created') t.equal(proofs instanceof Array, true, "Proofs should be an Array") t.equal(proofs.length, totalProofs, "Should have a proof for each of the 3 claimed accounts") FetchMock.restore() }) }) } export function runProofStatementUnitTests() { test('getProofStatement', (t) => { t.plan(7) const larry = sampleVerifications.larry const naval = sampleVerifications.naval const ken = sampleAddressBasedVerifications.ken t.equal(profileServices.facebook.getProofStatement(larry.facebook.body), 'Verifying that "larry.id" is my Blockstack ID.', 'Should extract proof statement from Facebook page meta tags') t.equal(profileServices.twitter.getProofStatement(naval.twitter.body), 'Verifying myself: My Bitcoin username is +naval. https://t.co/DdpZv8tMAH #bitcoin', 'Should extract proof statement from Twitter page meta tags') t.equal(profileServices.twitter.getProofStatement(ken.twitter.body), 'Verifying my Blockstack ID is secured with the address 1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', 'Should extract address-based proof statement from Twitter page meta tags') t.equal(profileServices.instagram.getProofStatement(ken.instagram.body), 'Verifying my Blockstack ID is secured with the address 1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', 'Should extract address-based proof statement from Instagram meta tags') t.equal(profileServices.hackerNews.getProofStatement(ken.hackerNews.body), 'Verifying my Blockstack ID is secured with the address 1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', 'Should extract address-based proof statement from Hacker News profile') t.equal(profileServices.linkedIn.getProofStatement(ken.linkedIn.body), 'Verifying my Blockstack ID is secured with the address 1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', 'Should extract address-based proof statement from Hacker News profile') t.equal(profileServices.linkedIn.getProofStatement(ken.linkedInBroken.body), '', 'Should not crash on broken LinkedIn proof link') }) } export function runOwnerAddressBasedProofsUnitTests() { test('containsValidAddressProofStatement', (t) => { t.plan(12) const larry = sampleAddressBasedVerifications.larry const ken = sampleAddressBasedVerifications.ken const facebookProofStatement = profileServices.facebook.getProofStatement(larry.facebook.body) const twitterProofStatement = profileServices.twitter.getProofStatement(ken.twitter.body) const githubProofStatement = profileServices.github.getProofStatement(ken.github.body) const instagramProofStatement = profileServices.instagram.getProofStatement(ken.instagram.body) const hackerNewsProofStatement = profileServices.hackerNews.getProofStatement(ken.hackerNews.body) const linkedInProofStatement = profileServices.linkedIn.getProofStatement(ken.linkedIn.body) t.equals(containsValidAddressProofStatement(facebookProofStatement, '1EyuZ8qxdhHjcnTChwQLyQaN3cmdK55DkH', true), true, "Facebook post meta tags should contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(facebookProofStatement, 'differentBitcoinAddress', true), false, "Facebook post meta tags should not contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(twitterProofStatement, '1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', true), true, "Twitter status meta tags should contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(twitterProofStatement, 'differentBitcoinAddress', true), false, "Twitter status meta tags should not contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(githubProofStatement, '1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', true), true, "Github gist body should contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(githubProofStatement, 'differentBitcoinAddress', true), false, "Github gist body should not contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(instagramProofStatement, '1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', true), true, "Instagram body should contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(instagramProofStatement, 'differentBitcoinAddress', true), false, "Instagram body should not contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(hackerNewsProofStatement, '1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', true), true, "Hacker News body should contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(hackerNewsProofStatement, 'differentBitcoinAddress', true), false, "Hacker News body should not contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(linkedInProofStatement, '1AtFqXxcckuoEN4iMNNe7n83c5nugxpzb5', true), true, "LinkedIn body should contain valid bitcoin address proof statement") t.equals(containsValidAddressProofStatement(linkedInProofStatement, 'differentBitcoinAddress', true), false, "LinkedIn body should not contain valid bitcoin address proof statement") }) } export function runInBodyIdentityVerificationTests() { test('getProofIdentity', (t) => { t.plan(2) const ken = sampleAddressBasedVerifications.ken t.equal(profileServices.instagram.getProofIdentity(ken.instagram.body), 'blckstcktest', 'Should extract social proof identity from Instagram proof page body') t.equal(profileServices.linkedIn.getProofIdentity(ken.linkedIn.body), 'blck-stck', 'Should extract social proof identity from LinkedIn proof page body') }) } export function runProofUtilsUnitTests() { test('containsValidProofStatement', (t) => { t.plan(8) const naval = sampleVerifications.naval t.equal(containsValidProofStatement(naval.facebook.body, 'naval.id'), true, "Facebook post body should contain valid proof statement for naval.id") t.equal(containsValidProofStatement(naval.github.body, 'naval.id'), true, "Github gist post body should contain valid proof statement for naval.id") t.equal(containsValidProofStatement(naval.twitter.body, 'naval.id'), true, "Twitter post body should contain valid proof statement for naval.id") const larry = sampleVerifications.larry t.equal(containsValidProofStatement(naval.facebook.body, 'larry.id'), false, "Github gist post body should not contain valid proof statement for larry.id") t.equal(containsValidProofStatement(naval.github.body, 'larry.id'), false, "Github gist post body should not contain valid proof statement for larry.id") t.equal(containsValidProofStatement(naval.twitter.body, 'larry.id'), false, "Github gist post body should not contain valid proof statement for larry.id") t.equal(containsValidProofStatement(larry.facebook.body, 'larry.id'), true, "Facebook post body should contain valid proof statement for larry.id") t.throws(() => { containsValidProofStatement(larry.facebook.body, 'larry') }, /Error/, "Using non-fully qualified blockstack name should throw exception") }) } export function runProofServicesUnitTests() { test('normalize Facebook URLs', (t) => { t.plan(6) t.equal(profileServices.facebook.normalizeFacebookUrl( { service: 'facebook', proof_url: "https://www.facebook.com/navalr/posts/10152190734077261", identifier: "navalr" }), "https://www.facebook.com/navalr/posts/10152190734077261", "Facebook URL should be normalized") t.equal(profileServices.facebook.normalizeFacebookUrl( { service: 'facebook', proof_url: "https://facebook.com/navalr/posts/10152190734077261", identifier: "navalr" }), "https://www.facebook.com/navalr/posts/10152190734077261", "Facebook URL should be normalized") t.equal(profileServices.facebook.normalizeFacebookUrl( { service: 'facebook', proof_url: "https://www.facebook.com/larrysalibra/posts/10100341028448093", identifier: "larrysalibra" }), "https://www.facebook.com/larrysalibra/posts/10100341028448093", "Facebook URL should be normalized") t.notEqual(profileServices.facebook.normalizeFacebookUrl( { service: 'facebook', proof_url: "https://www.facebook.com/larry.salibra/posts/10100341028448093", identifier: "larry.salibra" }), "https://www.facebook.com/larrysalibra/posts/10100341028448093", "Facebook URL should be normalized") t.notEqual(profileServices.facebook.normalizeFacebookUrl( { service: 'facebook', proof_url: "https://facebook.com/larry.salibra/posts/10100341028448093", identifier: "larry.salibra" }), "https://www.facebook.com/larrysalibra/posts/10100341028448093", "Facebook URL should be normalized") t.equal(profileServices.facebook.normalizeFacebookUrl( { service: 'facebook', proof_url: "https://facebook.com/larrysalibra/posts/10100341028448093", identifier: "larrysalibra" }), "https://www.facebook.com/larrysalibra/posts/10100341028448093", "Facebook URL should be normalized") }) test('normalize Instagarm URLs', (t) => { t.plan(4) t.equal(profileServices.instagram.normalizeInstagramUrl( { service: 'instagram', proof_url: "https://www.instagram.com/p/BZ7KMM0A-Qc/", identifier: "blckstcktest" }), "https://www.instagram.com/p/BZ7KMM0A-Qc/", "Instagram URL should be normalized") t.equal(profileServices.instagram.normalizeInstagramUrl( { service: 'instagram', proof_url: "https://instagram.com/p/BZ7KMM0A-Qc/", identifier: "blckstcktest" }), "https://www.instagram.com/p/BZ7KMM0A-Qc/", "Instagram URL should be normalized") t.equal(profileServices.instagram.normalizeInstagramUrl( { service: 'instagram', proof_url: "http://www.instagram.com/p/BZ7KMM0A-Qc/", identifier: "blckstcktest" }), "https://www.instagram.com/p/BZ7KMM0A-Qc/", "Instagram URL should be normalized") t.equal(profileServices.instagram.normalizeInstagramUrl( { service: 'instagram', proof_url: "http://instagram.com/p/BZ7KMM0A-Qc/", identifier: "blckstcktest" }), "https://www.instagram.com/p/BZ7KMM0A-Qc/", "Instagram URL should be normalized") }) test('get proof url', (t) => { t.plan(10) t.equal(profileServices.facebook.getProofUrl(sampleProofs.naval[1]), "https://www.facebook.com/navalr/posts/10152190734077261", "Facebook proof URL should match reference") t.equal(profileServices.github.getProofUrl(sampleProofs.naval[2]), "https://gist.github.com/navalr/f31a74054f859ec0ac6a/raw", "Github proof URL should match reference") t.equal(profileServices.twitter.getProofUrl(sampleProofs.naval[0]), "https://twitter.com/naval/status/486609266212499456", "Twitter proof URL should match reference") t.equal(profileServices.facebook.getProofUrl(sampleProofs.larry[0]), "https://www.facebook.com/larry.salibra/posts/10100341028448093", "Facebook proof URL should match reference") t.equal(profileServices.instagram.getProofUrl(sampleProofs.ken[0]), "https://www.instagram.com/p/BYj6UDwgaX7/", "Instagram proof URL should match reference") t.equal(profileServices.hackerNews.getProofUrl(sampleProofs.ken[1]), "https://news.ycombinator.com/user?id=yukanl", "Hacker News proof URL should match reference") t.equal(profileServices.linkedIn.getProofUrl(sampleProofs.ken[2]), "https://www.linkedin.com/feed/update/urn:li:activity:6311587377647222784/", "LinkedIn proof URL should match reference") // t.throws(() => { // const notLarry = Object.assign({}, // sampleProofs.larry[0], { // proof_url: 'https://www.facebook.com/not.larry/posts/10100341028448093' // }) // profileServices.facebook.getProofUrl(notLarry) // }, /Error/, 'Not having claimed account identifier in Facebook proof URL should throw exception') t.throws(() => { const notNavalTwitter = Object.assign({}, sampleProofs.naval[0], { proof_url: 'https://twitter.com/not_naval/status/486609266212499456' }) profileServices.twitter.getProofUrl(notNavalTwitter) }, /Error/, 'Not having claimed account identifier in Twitter proof URL should throw exception') t.throws(() => { const notNavalGithub = Object.assign({}, sampleProofs.naval[2], { proof_url: 'https://gist.github.com/not_naval/f31a74054f859ec0ac6a' }) profileServices.github.getProofUrl(notNavalGithub) }, /Error/, 'Not having claimed account identifier in Github proof URL should throw exception') t.throws(() => { const notKenHackerNews = Object.assign({}, sampleProofs.ken[0], { proof_url: 'https://news.ycombinator.com/user?id=notken' }) profileServices.github.getProofUrl(notKenHackerNews) }, /Error/, 'Not having claimed account identifier in Hacker News proof URL should throw exception') }) } export function runProofsUnitTests() { // Proof utils runProofUtilsUnitTests() // Proof statements runProofStatementUnitTests() // Proof address based runOwnerAddressBasedProofsUnitTests() // Proof identity extract from response body runInBodyIdentityVerificationTests() // Proof services runProofServicesUnitTests() // Proof HTML testProofs(sampleProfiles.naval, "naval.id", 3) testProofs(sampleProfiles.larry, "larry.id", 1) }