Skip to content

Commit

Permalink
fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
trevormil committed Jan 17, 2024
1 parent 75bb97f commit 70282d8
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 17 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

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

13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blockin",
"version": "1.2.79",
"version": "1.2.83",
"description": "",
"files": [
"dist"
Expand Down Expand Up @@ -45,6 +45,7 @@
},
"prepublishOnly": "npm run build",
"devDependencies": {
"@ant-design/icons": "^5.2.5",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
Expand All @@ -53,6 +54,7 @@
"@types/react": "^18.0.8",
"@types/react-blockies": "^1.4.1",
"@types/react-dom": "^16.9.14",
"antd": "^5.8.4",
"babel-loader": "^8.2.2",
"node-sass": "^8.0.0",
"postcss": "^8.4.31",
Expand All @@ -63,8 +65,7 @@
"rollup-plugin-typescript2": "^0.31.2",
"sass-loader": "^10.4.1",
"typedoc": "^0.25.4",
"typescript": "^4.5.5",
"antd": "^5.8.4",
"@ant-design/icons": "^5.2.5"
}
}
"typescript": "^4.5.5"
},
"dependencies": {}
}
13 changes: 11 additions & 2 deletions src/ui/SignInModal/SignInModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,20 @@ const BlockinUIDisplay: React.FC<SignInModalProps<NumberType>> = ({
}) => {
const [selectedUris, setSelectedUris] = useState<string[]>(getDefaultSelectedResources(displayedResources, displayedAssets).selectedUris);
const [selectedAssets, setSelectedAssets] = useState<string[]>(getDefaultSelectedResources(displayedResources, displayedAssets).selectedAssets);

const [displayMessage, setDisplayMessage] = useState('');
const [chain, setChain] = useState(getChain(selectedChainName, selectedChainInfo));
const [assetId, setAssetId] = useState('');
const [uri, setUri] = useState('');
const [loading, setLoading] = useState('');

const [advancedIsVisible, setAdvancedIsVisible] = useState(false);

const [hours, setHours] = useState(24);

useEffect(() => {
setSelectedUris(getDefaultSelectedResources(displayedResources, displayedAssets).selectedUris);
setSelectedAssets(getDefaultSelectedResources(displayedResources, displayedAssets).selectedAssets);
}, [displayedAssets, displayedResources])

/**
* This will be true when 1) there are no selectable resources passed in by provider and 2) user can not add custom
* resources.
Expand Down Expand Up @@ -125,6 +129,11 @@ const BlockinUIDisplay: React.FC<SignInModalProps<NumberType>> = ({
setDisplayMessage('');

const assetsToVerify: PresetAsset<NumberType>[] = selectedAssets.map(asset => displayedAssets.find(elem => `${elem.name}` === asset) as PresetAsset<NumberType>);
if (assetsToVerify.some(x => !x)) {
setDisplayMessage('Error: Asset not found.');
throw 'Error: Asset not found.'
}

/**
* Generate the challenge object by and input the selectedUris
*/
Expand Down
45 changes: 45 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export function compareObjects(obj1: any, obj2: any): boolean {
if (obj1 === obj2) {
return true;
}

if (typeof obj1 !== typeof obj2 || typeof obj1 !== 'object' || obj1 === null || obj2 === null) {
return false;
}

if (Array.isArray(obj1) !== Array.isArray(obj2)) {
return false;
}

if (Array.isArray(obj1)) {
if (obj1.length !== obj2.length) {
return false;
}

for (let i = 0; i < obj1.length; i++) {
if (!compareObjects(obj1[i], obj2[i])) {
return false;
}
}
} else {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);

if (keys1.length !== keys2.length) {
return false;
}

for (let key of keys1) {
if (!obj2.hasOwnProperty(key) || !compareObjects(obj1[key], obj2[key])) {
return false;
}
}
}

if (typeof obj1 === 'bigint' || typeof obj2 === 'bigint') {
return BigInt(obj1) === BigInt(obj2);
}


return true;
}
38 changes: 31 additions & 7 deletions src/verify.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IChainDriver, IChainDriverWithHelpers } from './index.js';
import { Asset, ChallengeParams, CreateChallengeOptions, NumberType, UintRange, VerifyChallengeOptions } from './types/verify.types.js';
import { compareObjects } from './utils.js';

const URI_REGEX: RegExp = /\w+:(\/?\/?)[^\s]+/;
const ISO8601_DATE_REGEX: RegExp = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/
Expand All @@ -8,19 +9,34 @@ const BigIntify = (item: NumberType) => {
return BigInt(item);
}

function getChainForAddress(address: string) {
let addr: string = address;
if (addr.startsWith('0x')) {
return 'Ethereum';
} else if (addr.startsWith('cosmos')) {
return 'Cosmos';
} else if (address.length == 44) {
return 'Solana';
} else if (address.startsWith('bc')) {
return 'Bitcoin';
}

return 'Web3'
}


/**
* Creates a challenge that is well-formed according to EIP-4361 - Sign in With Ethereum. Some
* slight modifications to EIP-4361 for our library include 1) any blockchain's native address, signature,
* and verification schemes are supported and 2) in resources, one may prefix an asset with 'Asset ID: '
* to specify micro-authorizations or role-based access using an on-chain asset.
*
* @param challengeParams - JSON object with the challenge details such as domain, uri, statement, address, etc.
* @param chainName - Name of the blockchain to include in the statement - "Sign in with your ____ account"
* @param options - JSON object speicfying any additional options when creating the challenge
* @returns Well-formed challenge string to be signed by the user, if successsful. Error string is returned
* upon failure.
*/
export function createChallenge<T extends NumberType>(challengeParams: ChallengeParams<T>, chainName?: string, options?: CreateChallengeOptions): string {
export function createChallenge<T extends NumberType>(challengeParams: ChallengeParams<T>, options?: CreateChallengeOptions): string {
/**
* This function should remain completely ChainDriver free. ChainDriver dependencies tend to mess up the
* React component generation in the browser.
Expand Down Expand Up @@ -59,7 +75,7 @@ export function createChallenge<T extends NumberType>(challengeParams: Challenge

validateChallengeObjectIsWellFormed(challenge); // will throw error if invalid

return constructChallengeStringFromChallengeObject(challenge, chainName);
return constructChallengeStringFromChallengeObject(challenge);
} catch (error: unknown) {
throw `Error: ${error} - ${challengeParams.toString()}`;
}
Expand Down Expand Up @@ -109,11 +125,17 @@ export async function verifyChallenge<T extends NumberType>(
await verifyChallengeSignature(chainDriver, message, signature)

if (options?.expectedChallengeParams) {


for (const key of Object.keys(options?.expectedChallengeParams ?? {})) {
if (challenge[key as keyof ChallengeParams<T>] !== options?.expectedChallengeParams[key as keyof VerifyChallengeOptions['expectedChallengeParams']]) {
throw `Error: unexpected value for ${key}: ${challenge[key as keyof ChallengeParams<T>]}. Expected ${options?.expectedChallengeParams[key as keyof VerifyChallengeOptions['expectedChallengeParams']]}`
const expected = JSON.parse(JSON.stringify(options?.expectedChallengeParams[key as keyof ChallengeParams<bigint>]));
const actual = JSON.parse(JSON.stringify(challenge[key as keyof ChallengeParams<bigint>]));
if (compareObjects(expected, actual) !== true) {
throw `Error: unexpected value for ${key}: ${JSON.stringify(challenge[key as keyof ChallengeParams<bigint>])} !== ${JSON.stringify(options?.expectedChallengeParams[key as keyof ChallengeParams<bigint>] ?? 'undefined')}`;
}

}

}
const toSkipAssetVerification = options?.skipAssetVerification ?? false;
if (challenge.resources || challenge.assets) {
Expand Down Expand Up @@ -354,9 +376,11 @@ export function validateChallengeObjectIsWellFormed<T extends NumberType>(challe
* @param chainName - Name of the blockchain to include in the statement - "Sign in with your ____ account"
* @returns - Well-formatted EIP-4361 challenge string to be signed.
*/
export function constructChallengeStringFromChallengeObject<T extends NumberType>(challenge: ChallengeParams<T>, chainName?: string): string {
export function constructChallengeStringFromChallengeObject<T extends NumberType>(challenge: ChallengeParams<T>): string {
const chain = getChainForAddress(challenge.address);

let message = "";
message += `${challenge.domain} wants you to sign in with your ${chainName ? chainName : 'Web3'} account:\n`
message += `${challenge.domain} wants you to sign in with your ${chain} account:\n`
message += `${challenge.address}\n\n`;
if (challenge.statement) {
message += `${challenge.statement}\n`;
Expand Down

0 comments on commit 70282d8

Please sign in to comment.