ServiceStack CredentialsAuthProvidercheck if authenticated - servicestack

Is there an easy way I can easily check whether I am currently logged into ServiceStack Auth by using a REST endpoint?

ServiceStack v4 has been recently updated, Friday 16 May, (in this commit) to support returning session information by making a GET request to the Authenticate route /auth.
Thus if you have a valid session you will get a response such as:
{
"UserId":"1",
"SessionId":"1",
"UserName":"bob",
"ResponseStatus":{}
}
Otherwise you can always create a service that returns information about your session yourself. See my other answer for an example of this method.
Hope that helps.

Related

How can I get all envelopes status and their signers status in one request?

Is it possible to call the DocuSign API with the "docusign-client"-library in order to get status information about all envelopes with all of their recipients/signers in one request?
When we call the "EnvelopesApi.ListStatusAsync" method of the docusign client library we just retrieve an array of envelopes but without the status information of their signees.
public async Task<EnvelopesInformation> GetListStatus(EnvelopeIdsRequest envelopeIds, ListStatusOptions opt) {
return await Request(async api => await api.ListStatusAsync(settings.AccountId, envelopeIds, opt));
}
It seems that this information have to be determine in second request by calling
"EnvelopesApi.ListRecipientsAsync" method for every envelope.
Maybe someone have an idea or know how to call the API properly.
Are there any options we have to consider by calling the API or do we need to configure something in the DocuSign dashboard?
Thanks!
Remarks: In our environment we can't use webhooks. So we have to poll the DocuSign API.
No, it's not possible and maybe we should understand your statement about "we can't use webhooks".
My guess is that you have firewall or some private network and you can't have calls from outside into these servers. That's not a reason not to use webhooks.
There's a simple solution to this involving an intermediary cloud account that gets your webhooks and a queue mechanism for you to check for messages.
Here is a blog post by Larry that can help if you are willing to consider webhooks.
Yes, you're right. The main reason why we can't use webhooks is because the applicationn is behind a firewall and our customer do not want to make any changes on that.
Also I know the possibility of using DouSign with services like Azure or AWS to get notification about their bus-messaging system but this is something we do not want to implement yet. Maybe in the future.
We found out that we can use the "EnvelopesApi.ListStatusChangesAsync" method to get all of the status information we're interested in.
var options = new ListStatusChangesOptions {
envelopeIds = ids,
include = "recipients"
};
var result = await client.ListStatusChangesAsync(options);

Node & GraphQL Auth

What is the recommended method of handling user authentication and token creation using Node/Graphql? I see a lot of tutorials out there that use a REST endpoint to authorize the user and generate the token.
While I'm new to the GraphQL scene, I don't see why you wouldn't use GraphQL for this.
For example, why not have a query like this which gets sent to a resolver that checks the user/pass and generates a token? :
mutation {
loginUser (
username: "YOURUSERNAME",
password:"YOURPASSWORD"
)
{
token
}
}
Is there a specific reason that the tutorials I've gone through haven't done it this way? Is there some sort of flaw in this method that I'm not aware of?
The official docs explain the reasoning a bit: https://graphql.org/graphql-js/authentication-and-express-middleware/
Reading between the lines a bit, it seems there isn't any official recommendation to not do this, but existing tools expect headers to be used and classic endpoints so this fits better.
If you start talking about OAUTH you're going to have to implement classic URLs anyways as well to complete that dance.

How to access "current logged-in user" in remote methods?

recently in one of my applications I needed to access currently logged-in user data for saving in another model (something like the author of a book or owner of a book). in my googling, I encountered these references but none of them was useful.
https://github.com/strongloop/loopback/issues/1495
https://docs.strongloop.com/display/public/LB/Using+current+context
...
all of them have this problem about accessing context or req object. after three days I decided to switch to afterRemote remote hook and add Owner or Author on that stage.
but something was wrong with this solution.
in strongloop's documentations (https://docs.strongloop.com/display/public/LB/Remote+hooks) there is a variable as ctx.req.accessToken that saves current logged-in user access token. but in the application this variable is undefined.
instead, I found accessToken in ctx.req.query.access_token and it was currently access_token variable that is sent to the server.
here is my problem:
is this variable (ctx.req.query.access_token) always available or
it's just because loopback-explorer send access_token as GET
variable?
in production mode do applications need to send access_token as
GET variable or it should be sent as Authorization in the header?
why ctx.req.accessToken is undefined?
could these things change over time? cause most of users encounter this problem due to deprecation of app.getCurrentContext()
Is this variable (ctx.req.query.access_token) always available or
it's just because loopback-explorer send access_token as GET
variable?
Well if your application always sends in the querystring, then it'll be always available for you, but it also sent in the header, or cookie or in the request body, but I don't suggest using it because it if the user logged in and the access token is valid and ctx.req.accessToken should be available and you can use it.
In production mode do applications need to send access_token as
GET variable or it should be sent as Authorization in the header?
I believe Authorization header is preferred, as if you send it in a GET variable, well it'll be visible in the logs and someone with the access to the logs can access the session(well unless you trust everyone), other than this it's fine to have it in a GET variable. Though I believe loopback client SDKs(Angular, Android, iOS) all send it via Authorization header by default, so you might have to configure them(maybe not possible).
Why ctx.req.accessToken is undefined?
Sometimes the context is lost thanks to the database drivers connection pooling, or the context req is lost(ctx.req) and they are null.
Assuming ctx.req is defined(because sometimes it's not), then probably that means the user is not logged it, or it's access token wasn't valid(expired or not in database). Also it could be a bug(maybe misconfiguration on your side), which also means for you that you will authentication problems.
Could these things change over time? cause most of users encounter this problem due to deprecation of app.getCurrentContext()
app.getCurrentContext is risky to use and I don't suggest unless you have no other solution. If you use it and it works, it might stop working if the database driver changes or in some corner cases that you haven't tested it, it might not work.
In the updated doc https://loopback.io/doc/en/lb3/Using-current-context.html
add this in your remoting metadata
"accepts": [
{"arg": "options", "type": "object", "http": "optionsFromRequest"}
]
then
MyModel.methodName = function(options) {
const token = options && options.accessToken;
const userId = token.userId
}
but it says
In LoopBack 2.x, this feature is disabled by default for compatibility reasons. To enable, add "injectOptionsFromRemoteContext": true to your model JSON file.
so add "injectOptionsFromRemoteContext": true on your model.json file

Getting customized message from GCM using Web push notifications

I'm using Web push notifications with Chrome, and they work great. But now I want to deliver a custom message in my notifications. I can have my Service Worker call out to my site to get content, as is done at https://simple-push-demo.appspot.com/—which is fine if I want every recipient to see the same message.
Is there any way to get either the recipient’s registration_id or the message_id that GCM returns? If I could get either of these and include them in the callback to the service, I could customize the response.
Also, any info on when we might be able to include a payload in the call to GCM?
The registration_id and message_id fields aren't exposed, but if the user is previously authenticated to your app, any fetch() to the server from your Service Worker will include credentials (and session information) which you can use to identify them.
If that doesn't work for your case, you can store user/session information in IndexedDB.
Payloads are coming soon—likely Chrome 50 or 51—based on the Web Push protocol. It's a bit of extra overhead and work to configure the (required) encryption.
It's possible, but I wouldn't do it since it's specific to GCM, while other browsers use other services.
You can either create a unique ID for each user (like we're doing in Mercurius) and store it in IndexedDB, or you can use the entire endpoint URL as an ID.
Here's the snippet to get the registration_id:
self.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
var endpoint = subscription.endpoint;
var endpointParts = endpoint.split('/');
var gcmRegistrationID = endpointParts[endpointParts.length - 1];
console.log(gcmRegistrationID);
}
});
P.S.: It returns a promise, so make sure your service worker waits for the promise to be resolved.

Logout on ServiceStack v4

I have ServiceStack v4 service but when I call the auth/logout route (using either POST or GET) to logout the currently logged-in user, I get an error:
400 Not Empty
User Name cannot be empty
Password Cannot be empty
As I wouldn't expect users to enter credentials when logging out, I am surely missing something?
I have the AuthFeature registered during host initialisation, and I am using CredentialsAuthProvider. I have taken the code from Github so I can see how it works.
My Client Code:
var rest = Restangular.one('auth/logout').get();
//var result = rest.post({userName: userName});
this.requestTracker.addPromise(rest);
return rest;
After a lot of digging, this happens when you are using CredentialsAuthProvider. Within this class, a validator is defined that validates all instances of the Authenticate request. As the logout route uses the Authenticate request, this validator is fired.
I got round it by modifying the validator to:
RuleFor(x => x.UserName).NotEmpty().When(d => d.provider != "logout");
RuleFor(x => x.Password).NotEmpty().When(d => d.provider != "logout");
This is probably not the most elegant way of fixing long term, but got me up and running.
I know this question is old, but I recently have been struggling with the same thing. What occurs is that before the Authenticate.Post function is called, the validation cache is checked and the CredentialsAuthProvider which has the mentioned validator fails unless username and password are not empty.
Now, i'm not sure if it makes a difference if you only have that provider enabled or not - I've not tested. I actually have my own custom provider that subclasses CredentialsAuthProvider and it's the only one I register.
The only way currently is to either pass a non-empty (but useless) password and username, or modify your own custom provider, overriding the Authenticate function and using a modified version of the validator as mentioned above.

Resources