INDY Error 212 while executing createPairwise - hyperledger-indy

I am trying to execute createPairwise function of indy-sdk package.
It throws an INDY Error 212 => WalletItemNotFound.
(I also executed createAndStoreMyDid function)
Here is my code
let [myDid, myVerkey] = await sdk.createAndStoreMyDid(await indy.wallet.get(), {});
let theirVerkey = await sdk.keyForDid(await indy.pool.get(), await indy.wallet.get(), theirDid);
let meta = JSON.stringify({
theirEndpointDid: theirEndpointDid,
verified: false // Indicates that the owner of the agent has confirmed they want to stay connected with this person.
});
//FIXME: Check to see if pairwise exists
await sdk.createPairwise(await indy.wallet.get(), theirDid, myDid, meta);
Can anybody help me out?

In your code, there's actually 2 places where IndySDK 1.11.1 can throw 212 WalletItemNotFound.
1. The first is on this line:
let theirVerkey = await sdk.keyForDid(await indy.pool.get(), await indy.wallet.get(), theirDid);
IndySDK will first try to see if the DID under variable theirDid is not one of your DIDs, stored in your wallet. If no, it will try to find this DID on the ledger. If it's still not found, it will throw WalletItemNotFound. You can check out this behaviour in the IndySDK Rust code here:
https://github.com/hyperledger/indy-sdk/blob/v1.11.1/libindy/src/commands/did.rs#L331
2. However I assume this is not actually your case and you having this error coming out from
wait sdk.createPairwise(await indy.wallet.get(), theirDid, myDid, meta);
If you look how is this method implemented in Rust
https://github.com/hyperledger/indy-sdk/blob/v1.11.1/libindy/src/commands/pairwise.rs#L84
you will see that it's calling get_indy_record for both theirDid and myDid you've supplied. Hence you can't create pairwise record without having both DIDs stored in wallet first. You can assure your wallet contains theirDid by calling storeTheirDid method. In
sdk.storeTheirDid(wh, {did:'V4SGRU86Z58d6TV7PBUe6f', verkey: 'GJ1SzoWzavQYfNL9XkaJdrQejfztN4XqdsiV4ct3LXKL'} )
After calling this, you will be able to call createPairwise between you and them without an issue.
IndySDK version / caching note
I think you might be using some older version of IndySDK. In IndySDK 1.11.1 when keyForDid resolves something from ledger, it actually caches this data, so the code you've posted actually worked out of the box for me without an error.

Related

How to know if form is submitted without errors in puppeteer

I am trying to submit a form and I am testing for cases where the form won't submit due to invalid input. If the zip code I enter is valid, then this line of code will return null because there was no error message.
await self.page.waitForFunction(
'document.querySelector("#adr-zip-error")'
);
However I have to hard code a delay before this or set some kind of timeout to catch this error message.
I tried also checking if the form itself is null in the same way but again, it only works if I check after some amount of time as it takes time for the form to submit.
Is there a way to tell if a form is submitted successfully without using a hard coded delay?
This is not a general solution and is tailored to this problem. You could use waitForResponse
const response = await page.waitForResponse(response => response.url().startsWith("https://app.shipt.com/api/v1/customer_addresses"));
if (response.ok())
//success
or, you could just check input validity:
const invalid = await page.evaluate(() => document.querySelector('#adr-zip').getAttribute('aria-invalid') === "true");
After the submit you could do something like:
await Promise.race([
page.waitFor('#adr-zip-error'),
page.waitForNavigation()
])
and then
let error = await page.$('#adr-zip-error')
will let you know if the error happened first

Firebase authenticaiton error handling in unity

I have been struggling to find a solution for this and it seems that i'm doing something in the wrong way due to my limited knowladge, so here is the breakdown of the problem:
public void RegisterNewUser()
{
FetchRegisterInputValues();
if (CheckRegisterDataIntegrity())
{
_auth.CreateUserWithEmailAndPasswordAsync(_email, _password).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted)
{
HandleRegistrationErrors(task.Exception);
return;
}
// Firebase user has been created.
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
}
else if (!CheckRegisterDataIntegrity())
{
HandleRegistrationErrors(new AggregateException("passwords do not match"));
}
}
above is the Registration function that I got straight from Firebase docs, it's very straightforward
the FetchRegisterInputValues(); function gets the email and passwords, the CheckRegisterDataIntegrity() compares the password with the password conformation in the form, and finally HandleRegistrationErrors(task.Exception); is meant to fire a popup panel to show the error,
this is how HandleRegistrationErrors(task.Exception); looks
private void HandleRegistrationErrors(AggregateException errMsg)
{
print("its here from the errors method " + errMsg.Message);
registerErrorPopup.OpenNotification();
registerErrorPopup.description = errMsg.Message;
}
it's using a UI asset from the asset store, the .OpenNotification(); starts the animation and pops it up, and then im just showing the message.
Now, I got two problems, the first is when there is an error encountered by Firebase and the if (task.IsFaulted) Condition is true, the HandleRegistrationErrors function should be called, right?. well that's exactly what happens, except only the print("it's here from the errors method " + errMsg.Message); line gets called and the rest of the function does not execute, I thought at first that its a problem with asset, but I tried doing it manually (created a native UI with unity and used SetActive() method to start the popUp), but again only print method executed, I think its because of the
CreateUserWithEmailAndPasswordAsync is Asynchronous and I should handle errors accordingly, but I really don't know how to go about it and there is no documentation that I could find.
The second problem is how to get the correct Error Message because of the task.Exception.Message always returns me a "One or more errors occurred". while the task.Exception itself gives the right message but it's not formatted correctly.
The first question is the easiest. To update your code with the minimal amount of effort, just replace ContinueWith with ContinueWithOnMainThread will force logic onto the main thread. Also, you should avoid calling task.Result if task.Exception is non-null as it will just raise the exception (see the related documentation).
For the threading related stuff: I go into much more detail about threading with Firebase and Unity here and you can read about the ContinueWithOnMainThread extension here.
For your second issue, the issue you're running into is that task.Exception is an AggregateException. I typically just attach a debugger and inspect this when debugging (or let Crashlytics analyze it in the field), and my UI state is only concerned about success or failure. If you want to inspect the error, the documentation I linked for AggregateException recommends doing something like:
task.Exception.Handle((e) => Debug.LogError($"Failed because {e}"));
Although I would play with .Flatten() or .GetBaseException() to see if those are easier to deal with.
I hope this helps!
--Patrick

Dart: client.post() method in the http.dart package is hanging and isn't returning a future

I am currently implementing a simple ONVIF client program in dart and am having a bit of trouble with handling futures in the http.dart package.
In my code below, the client.post() method returns a Future<response> (containing body/header/status code and so on...) and in my case I would need to receive this before the if/else statement, hence why I have used await. Trouble is the program just hangs and doesn't proceed past the client.post()line.
I know I might need to do a client.close() somewhere but I've tried lots of different ways and nothing works. Here is my current code with some comments to try and explain it a bit:
// The Variables:
// reqSysDateAndTime is a soap message we are sending to the device.
// onvifDev is just a place where the device details are stored.
// probeMatch is a class that stores important info from the ws-discovery stage.
Future<String> checkXaddrsAndGetTime(Device onvifDev, ProbeMatch probeMatch) async {
// Set up the client and uri.
Uri uri = Uri.parse(probeMatch.xaddrs);
http.Client client = http.Client();
// Send the POST request, with full SOAP envelope as the request body
print('[Setup]: Listening for Date/Time response...');
Response response = await client.post(uri, body: reqSysDateAndTime);
print("${response.body}");
// Determine if the address is usable or not.
if (response != null) {
// Set this address as 'working'
onvifDev.xAddrs = probeMatch.xaddrs;
return response.body;
}
else {
return null; // The address does not work
}
}
I also know that this isn't an issue with the actual body of the request because if I do...
client.post(uri, body: reqSysDateAndTime).then((onValue) => print(onValue.body));
...instead, it will print out the response which I'm expecting.
I understand that this is probably a small fix that I'm missing but any help would be much appreciated.
Cheers.
To briefly answer my own question, turns out it was a silly error on my part where the address I was using was link-local - hence why it was hanging at client.post(). There is a nice method in the InternetAddress class here, amongst some other useful methods, which checks to see if the address is link-local or not.

Firebase Admin SDK Auth error "TOO_MANY_ATTEMPTS_TRY_LATER"

I'm using firebase admin sdk in my cloud functions and I'm getting error randomly in some executions when trying to get a user by uid .
let userRecord = await admin.auth().getUser(userId);
The error details are:
{"error":{"code":400,"message":"TOO_MANY_ATTEMPTS_TRY_LATER",
"errors":[{ "message":"TOO_MANY_ATTEMPTS_TRY_LATER",
"domain":"global","reason":"invalid"}]
}
}
My cloud function executes on a real time database write and can be triggered for multiple users. In total I have 4 auth function calls in one execution first is the above one, second call is to again get user by uid or email, third call is generateEmailVerificationLink and the last call is generatePasswordResetLink.
I have checked the rate limits in documentation for auth but there is no mention of rate limit for these operation. Also the error TOO_MANY_ATTEMPTS_TRY_LATER was only mentioned in REST API for sign up with email password.
If this error is due to rate limit what should I change to prevent this error given these 4 calls are necessary for the operation needed on database write?.
EDIT:
I have identified the actual call which is throwing too many attempts error. The calls auth().generateEmailVerificationLink() and auth().generatePasswordResetLink() throw this error when called too many times.
I called these two in loop with 100 iterations and waited for the promises. The first executions finishes without any errors i.e. 200 requests. But starting second execution as soon as the first one ends will throw the error of too many attempts. So I think these two calls have limit. Now I'm trying to reduce these calls and reuse the link information. Other calls like getUserByEmail works fine.
let promises = [];
let auth = admin.auth();
let hrstart = process.hrtime()
for (let i = 0; i < 100; i++) {
promises.push(auth.getUserByEmail("user email"));
promises.push(auth.generateEmailVerificationLink("user email", {url: `https://app.firebaseapp.com/path`}));
promises.push(auth.generatePasswordResetLink("user email", {url: `https://app.firebaseapp.com/path`}));
}
Promise.all(promises)
.then(value => {
let hrend = process.hrtime(hrstart);
console.log(hrend);
// console.log(value)
});
The error was specifically in the operation auth.createEmailLink. This function has following limit: 20QPS/I.P address where QPS is (query per second). This limit can be increased by submitting the use case to Firebase.
I got this information from firebase support after submitting my issue.
Link to my github issue: https://github.com/firebase/firebase-admin-node/issues/458
I was way under 20QPS but was receiving this exception. In fact, it would always throw the TOO_MANY_ATTEMPTS_TRY_LATER exception on the 2nd attempt.
It turned out to be usage of FirebaseAuth.DefaultInstance instead of instantiating a static instance thusly:
In class definition:
private readonly FirebaseApp _firebase;
In class constructor:
_firebase = FirebaseAdmin.FirebaseApp.Create();
In function:
var auth = FirebaseAuth.GetAuth(_firebase);
var actionCodeSettings = new ActionCodeSettings()
{
...
};
var link = await auth.GenerateEmailVerificationLinkAsync(email, actionCodeSettings);
return link;
In addition to the answer mentioned in https://stackoverflow.com/a/54782967/5515861, I want to add another solution if you found this issue while trying to create custom email verification.
Inspired by the response in this GitHub isssue https://github.com/firebase/firebase-admin-node/issues/458#issuecomment-933161448 .
I am also seeing this issue. I have not ran admin.auth().generateEmailVerificationLink in over 24hrs (from anywhere else or any user at all) and called it just now only one time (while deployed in the prod functions environment) and got this 400 TOO_MANY_ATTEMPTS_TRY_LATER error ...
But, the client did also call the Firebase.auth.currentUser.sendEmailVerification() method around same time (obviously different IP).
Could that be the issue?
My solution to this issue is by adding a retry. e.g.
exports.sendWelcomeEmail = functions.runWith({failurePolicy: true}).auth.user().onCreate(async (user) => {
functions.logger.log("Running email...");
const email = user.email;
const displayName = user.displayName;
const link = await auth.generateEmailVerificationLink(email, {
url: 'https://mpj.io',
});
await sendWelcomeEmail(email, displayName, link);
});
The .runWith({failurePolicy: true}) is key.
It s giving you an error because your cloud functions/backend call the generateEmailVerificationLink while at the same time the default behaviour of the Firebase is also doing the same and it is counted as 20QPS. It some weird Google Rate Limit accounting rule. So my solution is just to add a retry.
The Downside is, it is calling twice, so if the call is billable, it might be billable twice.

Meteor insert into collection appears to work, but remains empty

I'm doing a simple insert into a meteor collection that appears work, but leaves the collection empty.
The collection is defined properly on the server:
Meteor.publish("comments", function () {
return Comments.find();
});
Subscribed to properly in the client.js:
Meteor.subscribe("commments");
And set up properly on the model.js:
Comments = new Meteor.Collection("comments");
The insert code is as follows:
Meteor.methods({
addComment: function (options) {
check(options.post_id, String);
check(options.comment, NonEmptyString);
if (! this.userId)
throw new Meteor.Error(403, "You must be logged in to comment.");
if (options.comment.length > 1000)
throw new Meteor.Error(413, "Comment is too long");
var post = Posts.findOne(options.post_id);
if (! post)
throw new Meteor.Error(404, "No such post");
// add new comment
var timestamp = (new Date()).getTime();
console.log('Comment: ' + options.comment);
console.log('Post: ' + options.post_id);
console.log('UserId: ' + this.userId);
var saved = Comments.insert({
owner: this.userId,
post_id: options.post_id,
timestamp: timestamp,
text: options.comment});
console.log('Saved: ' + saved);
}
});
Once the insert is called, the console prints out the following:
Comment: Something
Post: xRjqaBBEMa6qjGnDm
UserId: SCz9e6zrpcQrKXYWX
Saved: FCxww9GsrDsjFQAGF
> Comments.find().count()
0
I have inserts into several other collections that work just fine (Posts being one of them as you can see the post ID in the code). In the docs ist said that if the insert errors out it will print to the console, but as you can see it appears to be working, yet is actually empty.
Thanks.
UPDATE: I did find that the data is being put into the database, but for some reason is not showing up. I'm not sure why the data is not being published properly since there are no filters on the find().
I'm not sure exactly what's wrong, but there's a few things to check here.
• First, this:
Meteor.publish("comments", function () {
return Comments.find();
});
directs the server to publish the Collection, but doesn't actually establish the collection server side.
You should have Comments = new Meteor.Collection("comments"); available on both the client and the server. I tend to put in a file called model.js like the examples tend to do.
• Second possibility, you don't have a subscribe function shown above, such as Meteor.subscribe("comments"); If you don't have a subscribe function, your client isn't going to know about it, even though it does exist in the collection.
You can test this theory by typing meteor mongo in the shell (with your Meteor app running), and db.comments.find() to see if your comments are actually in the database but not subscribed to.
Verify you do not have an error in your client code. With Meteor.call, if you do not initialize a variable you can have an error condition that will block reactive updating in your templates but continue to write fine to your console just before hand.
I've made that mistake which I talk about here:
http://doctormehmet.blogspot.com/2013/07/revoltdc-hackathon-20130622-iteration-3.html
Specifically I had something like
Template.mytemplate.helpers({
somevar: function({
if (some_session_var_set_by_a_call.party){
//do something
}
}
Now the somevar function gets called on render, before the Meteor.call returns. Therefore the variable some_session_var_set_by_a_call isn't set yet. The whole thing stops client side on the undefined error.

Resources