Skip to content

Commit

Permalink
Add odis-identifiers package (moved from celo/base) (#104)
Browse files Browse the repository at this point in the history
* Add odis-identifiers package (moved from celo/base)

* initial release should be 1.0.0


* identifiers, lint, test, work


* Take changes from celo-org/celo-monorepo#10317

---------

Co-authored-by: Aaron <aaron.deruvo@clabs.co>
  • Loading branch information
aaronmgdr and aaronmgdr authored Oct 25, 2023
1 parent 4ef97d1 commit 757b590
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-foxes-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@celo/odis-identifiers': major
---

Initial Release. Move functions Enum from @celo/base
5 changes: 5 additions & 0 deletions .changeset/tasty-gifts-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@celo/odis-identifiers': minor
---

Add Github Prefix
4 changes: 4 additions & 0 deletions .github/workflows/social-connect.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,16 @@ jobs:
uses: ./.github/actions/sync-workspace
with:
package-json-checksum: ${{ needs.install-dependencies.outputs.package-json-checksum }}
- name: Run Odis Identifier Tests
run: |
yarn --cwd=packages/odis-identifiers test
- name: Run Encrypted Backup tests
run: |
yarn --cwd=packages/sdk/encrypted-backup test
- name: Run Identity Tests
run: |
yarn --cwd=packages/sdk/identity test
- name: Upload Jest Test Results
uses: actions/upload-artifact@v3
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,4 @@ scripts/failedSDKs.json

packages/protocol/types/typechain-mento/*.d.ts
tmp
packages/odis-identifiers/lib
8 changes: 8 additions & 0 deletions packages/odis-identifiers/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/src
*.test.*
# exclude ts files and sourcemaps
*.map
*.ts

# include the .d.ts files
!lib/**/*.d.ts
6 changes: 6 additions & 0 deletions packages/odis-identifiers/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
preset: 'ts-jest',
rootDir: './src/',
testMatch: ['<rootDir>/**/?(*.)+(spec|test).ts?(x)'],
verbose: true,
}
20 changes: 20 additions & 0 deletions packages/odis-identifiers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@celo/odis-identifiers",
"author": "cLabs",
"license": "Apache-2.0",
"private": false,
"version": "0.0.1",
"description": "ODIS Identifier Prefixes and functions to hash identifiers",
"repository": "https://github.com/celo-org/social-connect",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"scripts": {
"build": "tsc -b .",
"clean": "tsc -b . --clean",
"test": "jest --runInBand",
"lint": "eslint ."
},
"devDependencies": {
"web3-utils": "1.10.0"
}
}
34 changes: 34 additions & 0 deletions packages/odis-identifiers/src/identifier.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { soliditySha3 } from 'web3-utils'
import { getIdentifierHash, IdentifierPrefix } from './index'
const sha3 = (v: string) => soliditySha3({ type: 'string', value: v })

const TEST_SALT = 'abcdefg'
const TEST_PLAINTEXT_IDENTIFIER = '+testIdentifier@'

const EXPECTED_HASH_FOR_PREFIX: Record<IdentifierPrefix, string> = {
[IdentifierPrefix.NULL]: '0x9ba535838da6c3b9e5052e63261deb872451a45d24cbbc2e0153a02b151702e3',
[IdentifierPrefix.PHONE_NUMBER]:
'0x1c404f57b436d75c6c63547c795d1d475c87dcd7bce6413fb016483e815335ee',
[IdentifierPrefix.EMAIL]: '0xaa47e9630a60f2e6667b310164b82d973124fc462e0361750fb36cf9f0e6ee16',
[IdentifierPrefix.TWITTER]: '0x9bb3eedf112f5ff18ec50467e2422fa1c2df01550fd650970e7aec3d52bc5ea9',
[IdentifierPrefix.FACEBOOK]: '0x883c8d998c5e75e7014fdcd1f75976032023fbfe89707d030f22367f501e08e8',
[IdentifierPrefix.INSTAGRAM]:
'0x3b212606f77d62fa85f636d76ab499306bed09f7f23e39db6aba348000c54d48',
[IdentifierPrefix.DISCORD]: '0xce7834e8e3c84180fab3a97b099dd131a78f9c91c3ae9753412423dc7ffdbdaa',
[IdentifierPrefix.TELEGRAM]: '0x65ecb839a118e293672aa7556dcff3f5d82dd142835e9d6f45b9539f252b3c6c',
[IdentifierPrefix.SIGNAL]: '0x34702bc6c5253a4d9521da1f45cec9eac3969c9cae7380aac422e2b872019182',
[IdentifierPrefix.GITHUB]: '0xd0a0e7f10b99db21f6a066398baa0bb50c4e8c1768d98104abc56ed000fe81c3',
}

describe('Identifier hashing', () => {
describe('Produces correct hash', () => {
Object.values(IdentifierPrefix).forEach((prefix: IdentifierPrefix) => {
it(`with IdentifierPrefix: ${prefix}`, () => {
const expectedHash = EXPECTED_HASH_FOR_PREFIX[prefix]
expect(getIdentifierHash(sha3, TEST_PLAINTEXT_IDENTIFIER, prefix, TEST_SALT)).toBe(
expectedHash
)
})
})
})
})
85 changes: 85 additions & 0 deletions packages/odis-identifiers/src/identifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// These functions were moved from the identity SDK because the protocol package
// and @celo/phone-utils both need these core identifier generation functions as well.
// The protocol package cannot depend on the identity SDK as is since this creates
// a non-trivial dependency cycle (currently, if A->B means "A depends on B",
// identity -> phone-number-privacy-common -> contractkit -> protocol).

export const PEPPER_SEPARATOR = '__'

// Docstring is duplicated in @celo/identity; make sure to update in both places.
/**
* Standardized prefixes for ODIS identifiers.
*
* @remarks These prefixes prevent collisions between off-chain identifiers.
* i.e. if a user's instagram and twitter handles are the same,
* these prefixes prevent the ODIS identifers from being the same.
*
* If you would like to use a prefix that isn't included, please put up a PR
* adding it to @celo/base (in celo-monorepo/packages/sdk/base/src/identifier.ts)
* to ensure interoperability with other projects. When adding new prefixes,
* please use either the full platform name in all lowercase (e.g. 'facebook')
* or DID methods https://w3c.github.io/did-spec-registries/#did-methods.
* Make sure to add the expected value for the unit test case in
* `celo-monorepo/packages/sdk/base/src/identifier.test.ts`,
* otherwise the test will fail.
*
* The NULL prefix is included to allow projects to use the sdk without selecting
* a predefined prefix or adding their own. Production use of the NULL prefix is
* discouraged since identifiers will not be interoperable with other projects.
* Please think carefully before using the NULL prefix.
*/
export enum IdentifierPrefix {
NULL = '',
PHONE_NUMBER = 'tel',
EMAIL = 'mailto',
TWITTER = 'twit',
FACEBOOK = 'facebook',
INSTAGRAM = 'instagram',
DISCORD = 'discord',
TELEGRAM = 'telegram',
SIGNAL = 'signal',
GITHUB = 'github',
}

// Docstring is duplicated in @celo/identity; make sure to update in both places.
/**
* Concatenates the identifierPrefix and plaintextIdentifier with the separator '://'
*
* @param plaintextIdentifier Off-chain identifier, ex: phone number, twitter handle, email, etc.
* @param identifierPrefix Standardized prefix used to prevent collisions between identifiers
*/
export const getPrefixedIdentifier = (
plaintextIdentifier: string,
identifierPrefix: IdentifierPrefix
): string => identifierPrefix + '://' + plaintextIdentifier

/**
* Helper function for getIdentifierHash in @celo/identity, so that this can
* be used in protocol tests without dependency issues.
*
* @remarks
* Concatenates the plaintext prefixed identifier with the pepper derived by hashing the unblinded
* signature returned by ODIS.
*
* @param sha3 Hash function (i.e. soliditySha3) to use to generate the identifier
* @param plaintextIdentifier Off-chain identifier, ex: phone number, twitter handle, email, etc.
* @param identifierPrefix Standardized prefix used to prevent collisions between identifiers
* @param pepper Hash of the unblinded signature returned by ODIS
*/
export const getIdentifierHash = (
sha3: (a: string) => string | null,
plaintextIdentifier: string,
identifierPrefix: IdentifierPrefix,
pepper: string
): string => {
// hashing the identifier before appending the pepper to avoid domain collisions where the
// identifier may contain underscores
// not doing this for phone numbers to maintain backwards compatibility
const value =
identifierPrefix === IdentifierPrefix.PHONE_NUMBER
? getPrefixedIdentifier(plaintextIdentifier, identifierPrefix) + PEPPER_SEPARATOR + pepper
: (sha3(getPrefixedIdentifier(plaintextIdentifier, identifierPrefix)) as string) +
PEPPER_SEPARATOR +
pepper
return sha3(value) as string
}
1 change: 1 addition & 0 deletions packages/odis-identifiers/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './identifier'
11 changes: 11 additions & 0 deletions packages/odis-identifiers/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@tsconfig/recommended",
"compilerOptions": {
"declaration": true,
"removeComments":true,
"rootDir": "src",
"outDir": "lib"
},
"include": ["src", "index.d.ts"],
"compileOnSave": true
}
1 change: 1 addition & 0 deletions packages/sdk/identity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@celo/base": "^5.0.4",
"@celo/utils": "^5.0.4",
"@celo/contractkit": "^5.0.4",
"@celo/odis-identifiers": "^0.0.1",
"@celo/phone-number-privacy-common": "^3.0.3",
"@types/debug": "^4.1.5",
"bignumber.js": "^9.0.0",
Expand Down
10 changes: 5 additions & 5 deletions packages/sdk/identity/src/odis/identifier.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { isE164Number } from '@celo/base/lib/phoneNumbers'
import {
IdentifierPrefix,
getIdentifierHash as baseGetIdentifierHash,
getPrefixedIdentifier,
IdentifierPrefix,
isE164Number,
} from '@celo/base'
} from '@celo/odis-identifiers'
import {
CombinerEndpointPNP,
KEY_VERSION_HEADER,
Expand All @@ -15,12 +15,12 @@ import { createHash } from 'crypto'
import debugFactory from 'debug'
import { BlsBlindingClient, WasmBlsBlindingClient } from './bls-blinding-client'
import {
AuthenticationMethod,
AuthSigner,
AuthenticationMethod,
EncryptionKeySigner,
ServiceContext,
getOdisPnpRequestAuth,
queryOdis,
ServiceContext,
} from './query'

const debug = debugFactory('kit:odis:identifier')
Expand Down

0 comments on commit 757b590

Please sign in to comment.