Releases: kristoferlund/ic-siwe
ic-siwe-js: v0.2.4
Added
- Support for Vue.
Usage with Vue
The Vue submodule comes with SiweIdentityProvider that makes the SiweManager available to all components in the app. It also provides a useSiwe hook that can be used to interact with the SiweManager instance.
1. Setup the SiweIdentityProvider component
In the App.vue component, initiate the SiweIdentityProvider with a reference to the SIWE provider canister to make it available to all child components.
<script setup lang="ts">
import { createSiweIdentityProvider } from "ic-siwe-js/vue";
import { canisterId } from "../../ic_siwe_provider/declarations/index";
createSiweIdentityProvider({
canisterId,
});
</script>
<template>
<!-- Your app components -->
</template>2. Initiate the login process
The login process is initiated by calling the login function. This function requests a SIWE message from the backend if it has not already been loaded. The user is asked to sign the message using their Ethereum wallet and the signed message is sent to the backend for authentication. Once the authentication is complete, the user's identity is stored in local storage and the identity state variable is updated with the new identity.
The loginStatus state variable can be used to indicate the status of the login process. Errors that occur during the login process are stored in the loginError state variable.
<script setup lang="ts">
import { useSiwe } from "ic-siwe-js/vue";
const siwe = useSiwe();
</script>
<template>
<div>
<button @click="siwe.login">
Login
</button>
<button @click="siwe.clear">
Logout
</button>
</div>
</template>ic-siwe-js: v0.2.2
Added
- Support for vanilla JS/TS projects. This should mean ic-siwe-js is usable with little to no headache in Svelte, Solid.JS and Lit. Vue still needs a custom submodule I believe.
Changed
- Library renamed to ic-siwe-js and moved to the ic-siwe monorepo.
SiweIdentityProvidernow requires only the canister id as a parameter.- React hook renamed from
useSiweIdentitytouseSiwe. - Project now uses xstate/store under the hood for state management instead of messy React Context.
Migration from v0.1.x
Replace dependency in package.json:
- "ic-use-siwe-identity": "^0.1.2",
+ "ic-siwe-js": "^0.2.2",Import new name React hook from new location:
- import { useSiweIdentity } from "ic-use-siwe-identity";
+ import { useSiwe } from "ic-siwe-js/react";Import SiweIdentityProvider from new location:
- import { SiweIdentityProvider } from "ic-use-siwe-identity";
+ import { SiweIdentityProvider } from "ic-siwe-js/react";Use new simplified config for SiweIdentityProvider:
- <SiweIdentityProvider<_SERVICE>
- canisterId={canisterId}
- idlFactory={idlFactory}
- >
+ <SiweIdentityProvider canisterId={canisterId}>v0.1.1
Changed
- Updated dependencies: ic-cdk, upgrading from 0.15.0 to 0.15.1
v0.1.0 - Security fixes, making nonce required
Important
This release introduces breaking changes with new call signatures for the prepare_login and login functions.
This PR focuses on improving the security and reliability of the SIWE (Sign-In with Ethereum) process by ensuring proper cleanup of SIWE messages, implementing nonce-based security measures, and validating signature expiration. These changes help prevent replay attacks and ensure that expired signatures are not accepted.
Key Changes
- Ensure Expired SIWE Messages Removal: Added logic to remove SIWE messages on failed login attempts to prevent stale data retention.
- Nonce Generation for SIWE Messages: Implemented nonce generation for SIWE messages to enhance security by preventing replay attacks.
- Signature Expiry Validation: Added functionality to return an error if a signature has expired.
Detailed Changes
Commits
- 6daf4563f95f4dc653cb717f053e45e2fed578b9:
- Fix: Remove stored SIWE message on failed login attempts.
- 0b1118b822201b5bb124cfc0bd505a3c9550e29a:
- Feature: Secure generated SIWE messages using a nonce.
- c4cd84dc3125408100e3f37a1138e4a4cd3b5c2d:
- Fix: Return error if signature has expired.
Detailed Code Changes
-
New Functionality:
- Added
is_expiredfunction inSignatureMapto check if a signature has expired:pub fn is_expired(&self, now: u64, seed_hash: Hash, delegation_hash: Hash) -> bool { let expiration = self .expiration_queue .iter() .find(|e| e.seed_hash == seed_hash && e.delegation_hash == delegation_hash); if let Some(expiration) = expiration { return now > expiration.signature_expires_at; } false }
- Modified
loginfunction to remove SIWE message on failed login attempts:match recover_eth_address(&message_string, signature) { Ok(recovered_address) => { if recovered_address != address.as_str() { siwe_messages.remove(address, nonce); return Err(LoginError::AddressMismatch); } } Err(e) => { siwe_messages.remove(address, nonce); return Err(LoginError::EthError(e)); } };
- Added
-
Nonce Implementation:
- Updated
prepare_loginto generate and include a nonce:pub fn prepare_login(address: &EthAddress) -> Result<(SiweMessage, String), EthError> { let nonce = generate_nonce(); let message = SiweMessage::new(address, &nonce); SIWE_MESSAGES.with_borrow_mut(|siwe_messages| { siwe_messages.insert(message.clone(), address, &nonce); }); Ok((message, nonce)) }
- Updated
-
Signature Expiry Validation:
- Added signature expiry validation in
witnessfunction:pub fn witness( seed: Hash, delegation_hash: Hash, ) -> Result<HashTree, DelegationError> { let seed_hash = hash::hash_bytes(seed); if signature_map.is_expired(get_current_time(), seed_hash, delegation_hash) { return Err(DelegationError::SignatureExpired); } let witness = signature_map .witness(seed_hash, delegation_hash) .ok_or(DelegationError::SignatureNotFound)?; Ok(witness) }
- Added signature expiry validation in
v0.0.7
ic_siwe
Changed
- Updated dependencies: candid, ic-cdk, ic-cdk-timers
ic_siwe_provider
Changed
- Updated dependencies: candid, ic-cdk, ic-stable-structures
v0.0.6
What's Changed
- Add/runtime feature
IncludeUriInSeedby @kristoferlund in #5 - Add/runtime feature
DisableEthToPrincipalMappingandDisablePrincipalToEthMappingby @kristoferlund in #6
Runtime Features
The runtime behaviour of the ic_siwe_provider canister and the ic_siwe library can be customized using the following settings:
IncludeUriInSeed
Default: URI is not included in the seed
When set, the URI is included in the seed used to generate the principal. Including the URI in the seed does not add any additional security in a scenario where ic_siwe_provider is deployed and configured to serve only one domain. However, if the ic_siwe library is used in a custom canister, that delagetes identities for more than one domain, it is recommended to enable this feature to ensure that the principal is unique for each domain.
runtime_features = opt vec { \
variant { IncludeUriInSeed } \
}; DisableEthToPrincipalMapping
Default: Mapping is enabled
When set, the mapping of Ethereum addresses to Principals is disabled. This also disables the canister endpoints get_principal.
runtime_features = opt vec { \
variant { DisableEthToPrincipalMapping } \
}; DisablePrincipalToEthMapping
Default: Mapping is enabled
When set, the mapping of Principals to Ethereum addresses is disabled. This also disables the canister endpoints get_address and get_caller_address.
runtime_features = opt vec { \
variant { DisablePrincipalToEthMapping } \
}; v0.0.10, ic-use-siwe-identity
Changed
- The
loginfunction now returns aPromisethat resolves to theIdentityof the logged in user. New signature:login: () => Promise<DelegationIdentity | undefined>. - Upgraded wagmi to v2.5.7.
- This introduces TanStack Query as an additional dependency.
- Also, this means the signture for
signMessageStatushas changed slightly tosignMessageStatus: "error" | "idle" | "pending" | "success".
- Upgraded viem to v2.8.4
v0.0.9, ic-use-siwe-identity
Changed
- Moved @dfinity/xxx dependencies from dependencies to peerDependencies to reduce package size.
v0.0.5
ic_siwe_provider
Fixed
- Pre-built provider canister did not include metadata, now fixed.
v0.0.4
ic_siwe
Aligning version numbers with ic_siwe_provider
Added
EthAddressandEthSignaturestructs for type safety.- Added basic validation of delegation targets. Duplicate targets are now rejected.
Changed
- Library functions now mostly returns custom error types instead of strings. As a result, many error messages now differ slighlty to previous version.
prepare_loginandloginnow requiresEthAddressandEthSignaturestructs instead of strings.- Replaced
create_user_canister_pubkeywith a more readable implementation.
ic_siwe_provider
Changed
- Service functions
prepare_login,loginandget_delegationhave been renamedsiwe_prepare_login,siwe_loginandsiwe_get_delegationrespectively. See ic_siwe_provider.did for details.