HelloSign Templates - Not showing Me (when sending) - hellosign-api

My app is being set up to use HelloSign through it's API. I'm trying to create a Template using a PDF I have. My goal is to have fields in the PDF that I can pre-fill in before sending it to the customer to their signature. I'm going to pre-fill things in like their full name, their account #, etc.
I've uploaded the PDF into the Template tool and added the custom fields using the GUI tool. However, as I've found on the documentation and other StackOverflow questions, I need to set these custom fields to "Me (when sending)" in the Assigned to setting. However, for me, this option doesn't appear at all (See image).
As a result, when my API calls the sendWithTemplate function with this as one of the parameters, I'm getting an error of "Invalid custom field parameters".
I'm on the Pro plan currently. Also, if HelloSign is reading this, you should let people on a free account use a template in test mode or something, no reason to make me sign up with CC to test using templates.
const opts = {
test_mode: 1,
template_id: templateId,
clientId: '<my client id>',
subject: 'Test Document',
message: 'Sign this test document',
signers: [
{
email_address: 'email#email.com',
name: 'Klay'
}
],
custom_fields: [
{ personName: "Klay Curry" }
]
};
HelloSign.signatureRequest.sendWithTemplate(opts).then((res) => {
console.log("RES", res);
}).catch((err) => {
console.log("ERR", err);
});

I'm a HelloSign API support engineer and happy to help.
Apologies, we are updating our documentation, but the custom field should be set to "Sender" which is the same as "Me (when sending)".
Also, the custom_fields object should be set like so with NodeJs:
custom_fields = [ { "name" : "personName", "value" : "Klay Curry" } ]
As for your piece about letting folks on a free account use a template in test mode, I believe if you just create a template past your template limit, it will automatically say that the template is locked and can be used in test_mode.
I will also reply to you on the ticket you opened for this.

Related

Importing PHP crypt MD5 passwords into Google Cloud Identity Platform?

I'm trying to import existing users from another application into Google Cloud Identity Platform using passwords that were hashed using PHP's crypt function with an MD5 output.
This is an example of the hashed password being used in PHP:
$hashed_password = '$1$AT$JGYIRSP7xIYmg1XSoJmvB1';
$user_input = 'test123';
if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
echo "Password verified!";
}
I've tried all sorts of combinations for importing the user and their password, but no combination seems to work. This is the NodeJS import script I'm using:
var admin = require('firebase-admin');
var app = admin.initializeApp({
credential: admin.credential.applicationDefault()
});
admin
.auth()
.importUsers(
[
{
uid: '31',
email: 'user31#test.test',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('$1$AT$JGYIRSP7xIYmg1XSoJmvB1'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('$1$AT$'),
},
],
{
hash: {
algorithm: 'MD5',
rounds: 0,
},
}
)
.then((results) => {
console.log(results);
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
As mentioned above, I've tried just about every combination of hash and passwordSalt I could think of. I've tried:
passing no passwordSalt
passing a passwordSalt of AT
passing a passwordSalt of AT$
passing a passwordSalt of $AT
passing a passwordSalt of $AT$
all of the above but with a hash algorithm of BCRYPT
I can see the user getting imported. If I change the hash to something like a regular MD5 hash, I'm able to authenticate as that user, so I know the import process is working correctly.
Does GCP Identity Platform simply not support these hashes? Am I passing the salt incorrectly or passing an incorrect number of rounds? Am I passing the wrong hash algorithm? I'm a little surprised, as I would've thought passwords hashed using PHP's crypt function would've been supported.
4 points:
1.- You are mentioning that you are trying to import existing users and their passwords from another application into Google Cloud Identity Platform. Also, you mentioned that you are using a NodeJS import script focused on MD5. Based on that, and using the same official GCP documentation that you quoted Migrating users from an existing app vs the NodeJS’s script you posted, it seems that you didn’t use the code sample that is posted in that documentation, exactly in the way it should be used, unless that you are the owner of the domain "#test.test":
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user#example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt'),
},
],
{
hash: {
algorithm: 'PBKDF2_SHA256',
rounds: 100000,
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
2.- Are we sure you have the required admin rights or role over IAM in your GCP’s Organization? You can use the following official GCP documentation for understanding roles Understanding roles
3.- How are you figuring out that it is not working? Are you facing any of the following errors? Error codes. Is there any particular behavior after the importing process finishes or any log that you can share here editing your original post? Or is it only because you see that once the users are imported to IAM, they are not able to authenticate?
4.- I suggest you by now to follow (Method: users.insert) as stated here Method: users.insert first, this way you are going to review the hash formats that are supported. Finally, you need to do this test with the domains that you have verified in Cloud Identity.

GMB MyBusiness API - How to set up real-time PubSub notifications?

I am working on integrating GMB into some of our internal apps, and would like to set up to receive real-time notifications for reviews and questions.
I have created a topic, and a subscription with a valid URL.
The next step is to tell GMB to send the notifications to the topic, and I believe the endpoint is the one below. However, it is very vague about the parameters it wants.
This is the documentation
https://developers.google.com/my-business/reference/rest/v4/accounts/updateNotifications
It wants a "Notification Settings Resource Name" in the URL, but it's not explained anywhere what that actually is. I have tried every possible value, but always get a 404 error response with the message "Requested entity was not found."
Has anyone successfully set this up? What values does the "getNotifications" endpoint want, and where in the various dashboards can this be found or created?
Any help is much appreciated!
As mentioned in the comments, you need to send the accountId as part of the URL.
To find this, you will first need to send a GET request to
https://mybusiness.googleapis.com/v4/accounts
This will return something along the following lines:
{
"accounts": [
{
"name": "accounts/102647145453118950380",
"accountName": "Tom Spencer",
"type": "PERSONAL",
"state": {
"status": "UNVERIFIED",
"vettedStatus": "NOT_VETTED"
},
"profilePhotoUrl": "//lh3.googleusercontent.com/a-/AOh14GgPkuJj03DeCa1isBAJALY4eOl09WGYVFrM4mG5=s132"
},
]
}
You can see here that accounts/102647145453118950380 is returned in the name field. Take this field, and construct the following URL:
https://mybusiness.googleapis.com/v4/accounts/102647145453118950380/notifications
Send a PUT request to this URL, with a request body resembling the following:
{
"topicName": "projects/{projectId}/topics/{topicId}",
"notificationTypes": [
"NEW_REVIEW",
"UPDATED_REVIEW"
]
}
Assuming you have pub/sub setup as per the documentation, this should send a message to your topic/subscribers whenever a new review is created or a review is updated.

Can you manually set 'phone_number_verified' to true on an AWS Cognito user, without having the end user need to interact with your web-app?

We just solved an issue where entering a wrong phone number (starting digit was missing) resulted in 'phone_number_verified' defaulting to false. Now that the issue is resolved, we do still have a lot of registered users who have had an activation sent to them (and entered said code) whose statuses are CONFIRMED in AWS Cognito, but have the 'phone_number_verified' property still set to false. Is there any way to edit this property in bulk / per user in Cognito itself or is there an API call that needs to be made? Or any solution that does not require the end user to go through the activation process again themselves.
(Further Info)
- AngularJS as Front-End
- Node v6.9 as Back-End
The recommendation here is that the users should call GetUserAttributeVerificationCode and receive a code to verify the phone/email which is then supplied to VerifyUserAttribute. This will ensure that if their numbers are verified.
Although if you are sure that all of their numbers are verified, you can use AdminUpdateUserAttributes to mark them verified. We do not have a batch API right now.
The phone number verified can be set to true by using the following example payload:
let parameters = {
UserPoolId : `${USER_POOL_ID}`,
Username : `${Username}`,
UserAttributes : [
{
'Name': "phone_number" ,
'Value': `${phoneNumber}`
},{
'Name':"phone_number_verified",
'Value': "true"
}]
}
cognitoIdentityServiceProvider.adminUpdateUserAttributes(parameters,function (err, result) {
if(err)
console.log(err);
else
console.log("Attribute updated successfully");
})

Grails: Expose LoginController for programmatic login

So I am working on a Grails/Flex toy project. I have a controller(LoginController) that I am using to perform backend authentication on my Flex app. However, I have been unable to "find" my controller. What I mean by that is I get a HTTP Status 404 error when trying to access
http://localhost:8080/OrlandoGrails/LoginController/login.json
Here is my sad, sad little controller as it is in its proof-of-concept state.
package orlandograils
class LoginController {
static allowedMethods = [login: "POST", login: "GET"]
def login(String username, String password )
{
return "Hello"
}
}
I've seen the documentation concerning RESTful services, but they always seem to concern a domain object which I don't have. In any case, I have also added this to my UrlMappings.groovy file
"/LoginController/login.json"(resource:"LoginController")
Any help on what I'm doing horribly wrong would be greatly appreciated. Also, is there a way to list Grails routes like one can with RoR or Symfony2?
Also, while the bulk of my services will be over the amf channels, my authentication is occurring over http.
It isn't entirely clear what you are trying to accomplish but one problem with your sample is that in your URL mapping you are specifying the name of a controller as your resource, which doesn't make sense. That could be a domain class, but not a controller.
If all you want to do is map a url to particular action in the controller you can do something like this in UrlMappings.groovy...
"/LoginController/login.json"(controller: 'login', action: 'login')
Normally you wouldn't have "Controller" in the url so something like this would be more common...
"/login/login.json"(controller: 'login', action: 'login')
From the little code snippet it also isn't clear what role you want JSON to play. Maybe you just want something like this...
"/login"(controller: 'login', action: 'login')
If you can further describe what you are trying to accomplish I can clarify.
In regards to getting a listing of routes (e.g. URL Mappings) you can run grails url-mappings-report
Also note to modify url-mapping to look like:
"/LoginController/login.json"(controller: "login", action: "login")
If resource is used then default action methods has to be show, create, update and delete
//Using resource: would look for a show() action method for a GET
//request which you don't have in your case. And, note name of controller used
//is login instead of LoginController
"/LoginController/login.json"(resource: "login")
As far as the 404 is concerned it's looking for a corresponding view called "hello.gsp" If you want to render text then use:
render text: 'hello'
The original post includes this:
package orlandograils
class LoginController {
static allowedMethods = [login: "POST", login: "GET"]
def login(String username, String password )
{
return "Hello"
}
}
The allowedMethods property there is bogus. Keys in a Map have to be unique. That code attempts to put the key login in the Map twice. If the intent is to say that the login method may be accessed via POST or GET then this makes sense...
static allowedMethods = [login: ['POST', 'GET']]
The code as written is valid, but it doesn't do what it was probably intended to do. That Map will evaluate to only have 1 value associated with the login key. That doesn't have anything to do with Grails, that is just standard Map behavior.
$ groovysh
Groovy Shell (2.1.9, JVM: 1.7.0_45)
Type 'help' or '\h' for help.
-------------------------------------------------------------------------------
groovy:000> [login: 'GET', login: 'POST']
===> {login=POST}
groovy:000>
Notice that the expression evaluates to a Map with the value "POST" associated with the login key.

Load a model manually with EmberData

I have an Ember app with a login form which returns the current user in JSON format after successful login.
Using createRecord sets the returned JSON attributes directly on the model. For instance, is_private becomes user.is_private, not user.get('isPrivate')?
How do I load the user model so that the attributes are set correctly and I don't have to re-fetch it using the id?
As of a few days ago in ember data 1.0 beta you can use pushPayload to load data directly into the store. For example if you get data pushed to your app through WebSockets (we use the Heroku add-on Pusher). You can call it on the store (source) directly and it will pass it through the appropriate serializer:
var postsJSON = {
posts: [
{id: 1, post_title: "Great post"}
]
}
this.store.pushPayload('post',postsJSON)
NOTE that it will not currently load a singular object (ie post: {id: 1, post_title:"First!"}) - you need to format it as plural with an array.
DS.RESTSerializer has pushPayload as well (source), in which case you need to pass it the store instead.
I highly encourage reading the source code before using, as it looks like the implementation of it will be revisited.
Supposedly, the official way to do this is using adapter.load, as described in this thread:
Loading Data
Previously, some features of the store, such as load(), assumed a
single adapter.
If you want to load data from your backend without the application
asking for it (for example, through a WebSockets stream), use this
API:
store.adapterForType(App.Person).load(store, App.Person, payload);
This API will also handle sideloaded and embedded data. We plan to add
a more convenient version of this API in the future.
But unfortunately, it doesn't handle sideloaded data, despite what the documentation claims. I personally use something like the following, which is based on how find(ID) is implemented:
var id = json["person"]["id"];
var store = DS.get("defaultStore");
var adapter = store.adapterForType(App.Person);
adapter.didFindRecord(store, App.Person, json, id);
var person = App.Person.find(id);
Note that this code assumes JSON in the same format that find(ID) expects to receive from the server, as documented in the RESTAdapter guide:
{
person: {
id: 1,
is_private: false,
projects: [3]
},
projects: [
{ id: 3, name: "FooReader" }
]
}
This will apply any transformations you've configured using keyForAttributeName (such as mapping is_private to isPrivate), and it will handle sideloaded records. I'm not sure if this is a best practice, but it works quite well.
how about store.push('user', userJSON)?
http://emberjs.com/guides/models/pushing-records-into-the-store/#toc_pushing-records
All answers above did not work for me.
What only worked for me was:
this.store.buildRecord(this.store.modelFor('person'), data.id, data)