Last Login Date to Application - okta

I am looking for an API to find the user's last login date to a particular application. Not sure if it exists, please let me know your thoughts on getting this information through API calls.

You can get the last date the user was authenticated to any application on the User profile:
GET https://dev-12345.oktapreview.com/api/v1/users/xyz
{
"id": "xyz",
"status": "ACTIVE",
"created": "2017-02-22T02:33:02.000Z",
"activated": null,
"statusChanged": "2017-02-22T17:50:43.000Z",
"lastLogin": "2017-09-28T16:19:57.000Z",
"lastUpdated": "2017-08-08T20:11:46.000Z",
"passwordChanged": "2017-02-22T17:50:43.000Z",
"profile": {
"lastName": "Barbettini",
"firstName": "Nathanael",
// ...
}
The lastLogin field contains the timestamp of the last time the user logged in.
This isn't tracked on a per-app basis, though. You can get the app-specific App User:
GET https://dev-12345.oktapreview.com/api/v1/apps/abc/users/
{
"created": "2017-09-22T00:54:49.000Z",
"lastUpdated": "2017-09-22T00:54:49.000Z",
"scope": "GROUP",
"status": "ACTIVE",
"statusChanged": "2017-09-22T00:54:49.000Z",
"passwordChanged": null,
"syncState": "DISABLED",
"profile": {
"zoneinfo": "America/Los_Angeles",
"region": null,
// ...
}
But it doesn't have lastLogin. One way you could solve this is by saving a timestamp in the App User profile in your application code.

You could use filters to specify which logs do you want from the system logs API endpoint, limit the answer to 1, set the response order to start from the most recent ones, and user filters again to filter for your user.
So, you need to filter the request using the following filters:
actor.alternateId: which identifies the user, in my case the pattern "username#" is enough
event_type: this one should be user.authentication.sso which means that the user SSO to an app (any of the ones available for that user)
outcome.result: success, which means that the user successfully SSO to the app
Example query would be something like this:
curl -X GET -H "Content-Type: application/json" -H "Authorization: SSWS super-secret-token-here" -H "Accept: application/json" "https://<your.domain.here.com>/api/v1/logs?until=2018-07-17T11%3A30%3A55.664541&limit=1&sortOrder=DESCENDING&filter=event_type+eq+%22user.authentication.sso%22+and+outcome.result+eq+%22SUCCESS%22+and+actor.alternateId+sw+%22<user name here>%40%22"
Remember to replace the token, the URL and the before testing this query.
Also, remember that this example is URL encoded, so this is why it looks so weird.

Related

LinkToken with account filters - assets/investment/brokerage - not working

I am currently trying to retrieve the link token using a curl command in my terminal. I ultimately want to obtain the user's investment data in my app so I decided to use the assets product with account_filter of investment and subtype brokerage. However, this is not working.
Here is the request I am using (minus the IDs):
curl -X POST https://sandbox.plaid.com/link/token/create -H 'Content-Type: application/json' -d '{
"client_id": "...",
"secret": "...",
"user": { "client_user_id": "unique-per-user"
},
"client_name": "...",
"products": ["assets"],
"country_codes": ["US"],
"language": "en",
"redirect_uri": "...",
"account_filters": {
"investment": {
"account_subtypes": ["brokerage"]
}
}
}'
I then get the error:
{
"display_message": null,
"documentation_url": "https://plaid.com/docs/#create-link-token",
"error_code": "INVALID_FIELD",
"error_message": "account_filters must be nonempty Map\u003caccount type, Map\u003c\"account_subtypes\", Array\u003caccount subtype\u003e\u003e\u003e where account type and account subtype are strings. There must also be at least 1 valid product and account type combination.",
"error_type": "INVALID_REQUEST",
"request_id": "...",
"suggested_action": null
}%
UPDATE: I've confirmed with the Assets team that appears to be a bug / unintended behavior, they are looking into it.
I'm not entirely sure why, but it does seem like the Assets product does not support using account filters for anything other than depository accounts. Note that the Assets API is designed for lending use cases and gets a snapshot of a single point in time of a user's account balances and transactions. If you're looking to understand someone's investments, you in most cases probably want to use the Plaid Investments API, which allows you to view what a user is invested in, has automatic account filtering for investments accounts built in, and will keep you up-to-date with a user's current investments.

Strapi + MongoDB not saving password field

I am trying to save a password in password type field in Strapi with MongoDB, but is always empty. I am testing through API calls using Insomnia software. The endpoints are already enable in Strapi configuration and the data is stored, just password is missing. For example, doing a POST API call with this data:
{
"name": "Test",
"Password": "testpassword",
"email": "testmail#hotmail.com"
}
It is stored this way:
{
"_id": "6097eadeb01bb600159d9319",
"name": "Test",
"email": "testmail#hotmail.com",
"published_at": "2021-05-09T13:59:58.204Z",
"createdAt": "2021-05-09T13:59:58.211Z",
"updatedAt": "2021-05-09T13:59:58.211Z",
"__v": 0,
"id": "6097eadeb01bb600159d9319"
}
If I enter to Strapi and check the created user, the password field is missing too, and even if I enter it manually, it is not saved either.
The password field is not displayed on the admin panel for security reasons. but u can update it from the admin panel. you will have to over write the create function without using the sanitize(which removes the password from the response) in order to get the password in response.

Is pagination for Youtube API Channel Memberships (sponsors.list) broken?

I'm trying to paginate through a list of results using the youtube API for Channel Memberships (sponsors.list), but the paging and PageTokens don't seem to be working as they are supposed to.
I'm currently developing an application for a user to generate a list of all Members to their channel (using the api for sponsors.list: https://developers.google.com/youtube/v3/live/docs/sponsors/list)
I have a test account, and I've been able to successfully pull the list. However, the test account only has 5 memberships. Since the API can only pull a maximum of 50 results per page, I want to make sure that my app can account for the possibility that the channel will have 50+ sponsors.
So, I've set the results per page to give me just 1, theoretically giving me 5 pages I can then sift through to simulate 50+ members.
The problem arises when I try to page through the results... as the API says, I grab the nextPageToken from the results, and pass it in the next call in the pageToken parameter. However, when I do so, even when testing in the API explorer, I get back an empty list, and no nextPageToken for the next page.
{
"kind": "youtube#sponsorListResponse",
"etag": "\"XpPGQXPnxQJhLgs6enD_n8JR4Qk/UCSC321uKOiUT6GNkcPmkqoH1sY\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 0
},
"items": []
}
Additionally, if I pass a fake pageToken, the results come as if I'd passed no token at all, so it is at least recognizing the nextPageToken I'm passing it.
My google searches have failed me, other than just turning up pages talking about how the pagination is supposed to work... which it obviously isn't. Am I doing something wrong? Or is it indeed broken?
Edit
Here are the API calls I made.
Initial member list pull (After getting the authorization token, etc).
'https://www.googleapis.com/youtube/v3/sponsors?part=snippet&filter=all&maxResults=1' \
--header 'Authorization: Bearer [SECRET_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
Which results in: (I've edited out sensitive info, like [CHANNEL_ID], etc).
{
"kind": "youtube#sponsorListResponse",
"etag": "\"XpPGQXPnxQJhLgs6enD_n8JR4Qk/PRgb6wjx--gdhgTtZ1auDKOony0\"",
"nextPageToken": "GLiawvDS6uEC",
"pageInfo": {
"totalResults": 5,
"resultsPerPage": 1
},
"items": [
{
"kind": "youtube#sponsor",
"etag": "\"XpPGQXPnxQJhLgs6enD_n8JR4Qk/LoD6jhrr94l_4soca-7lx14kyRQ\"",
"snippet": {
"channelId": "[CHANNEL_ID]",
"sponsorDetails": {
"channelId": "[CHANNEL_ID]",
"channelUrl": "[CHANNEL_URL]",
"displayName": "[DISPLAY_NAME]",
"profileImageUrl": "[PROFILE_IMAGE_URL]"
},
"sponsorSince": "2019-04-25T06:36:11.677Z"
}
}
]
}
So I grab the nextPageToken "GLiawvDS6uEC", and drop that into my next call in the pageToken field, as the API instructs.
'https://www.googleapis.com/youtube/v3/sponsors?part=snippet&filter=all&maxResults=1&pageToken=GLiawvDS6uEC' \
--header 'Authorization: Bearer [SECRET_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
And wind up with this depressing result:
{
"kind": "youtube#sponsorListResponse",
"etag": "\"XpPGQXPnxQJhLgs6enD_n8JR4Qk/UCSC321uKOiUT6GNkcPmkqoH1sY\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 0
},
"items": []
}
So, turns out this was an actual problem with the API. Had a friend who knew someone at google, they looked into it, got the problem fixed! It works as intended now! Yay!
That said, if I hadn't had that connection, who knows if this would ever have been solved ;_;
As far as I can see, a nextPageToken of value GLiawvDS6uEC is invalid.
All the page tokens I came across were of a pattern described e.g. by Youtube Data API v3 pageToken for arbitrary page.
The API's documentation itself says nothing about how a page token should look like!
Maybe someone else has better inside on this issue. In any case, I suggest to file a report with Google.

Microsoft Graph - Can't read/write the calendar of other users

I have a web app registered on Azure with the goal of being able to read and write the calendars of other users. To do so, I set these permissions for this app on Azure.
However, when I try to, for example, create a new event for a given user, I get an error message. Here's what I'm using:
Endpoint
https://graph.microsoft.com/v1.0/users/${requester}/calendar/events
HTTP Header
Content-Type application/json
Request Body
{
"subject": "${subject}",
"body": {
"contentType": "HTML",
"content": "${remarks}"
},
"start": {
"dateTime": "${startTime}",
"timeZone": "${timezone}"
},
"end": {
"dateTime": "${endTime}",
"timeZone": "${timezone}"
},
"location": {
"displayName": "${spaceName}",
"locationEmailAddress": "${spaceEmail}"
},
"attendees": [
{
"emailAddress": {
"address": "${spaceEmail}",
"name": "${spaceName}"
},
"type": "resource"
}
]
}
Error message
{
"error": {
"code": "ErrorItemNotFound",
"message": "The specified object was not found in the store.",
"innerError": {
"request-id": "XXXXXXXXXXXXXXXX",
"date": "2018-07-11T09:16:19"
}
}
}
Is there something I'm missing? Thanks in advance for any help!
Solution update
I managed to solve the problem by following the steps described in this link:
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
From your screenshot it's visible that you used application permission (although it'd be nice to include this information in your question):
Depending on kind of the permission you have given, you need to use proper flow to obtain access token (on behalf of a user or as a service. For application permissions you have to use flow for service, not on behalf of a user.
You can also check your token using jwt.io and make sure it's payload contains appropriate role. If it doesn't, it's very likely you used incorrect flow.
Regarding the expiration time of it, you may have found the information about refresh token (for example here). Keep in mind that it applies only to rights granted on behalf of a user. For access without a user you should make sure that you know when your token is going to expire and request a new one accordingly.

googleapis giving back bad request

Having implemented oauth2.0 and done a handshake using the scopes:
"https://www.googleapis.com/auth/userinfo.email ",
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/admin.directory.user ",
"https://www.googleapis.com/auth/admin.directory.group ",
"https://www.googleapis.com/auth/admin.directory.orgunit ",
I get back a token
the request
$ curl -X GET https://www.googleapis.com/oauth2/v1/userinfo?access_token=<Token>
{
"id": "{id}",
"email": "{email}",
"verified_email": true,
"name": "{name}",
...
}
as it should.
however a requst to the admin.directory.user namespace does not succeed:
$ curl -X GET https://www.googleapis.com/admin/directory/v1/users?access_token=<Token>
{
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}
Any good ideas to why this is?
The request to admin.directory.users is constructed from https://developers.google.com/admin-sdk/directory/v1/reference/#Users
I had the same problem retrieving all users through https://www.googleapis.com/auth/admin.directory.user endpoint. According to the documentation, you could do that in a specific domain by passing the domain as a parameter or get all existing users by passing the customer=my_customer parameter as follows:
Retrieve all users in a domain doc: https://www.googleapis.com/auth/admin.directory.user?domain=example.com
or
Retrieve all account users doc: https://www.googleapis.com/auth/admin.directory.user?customer=my_customer
In google playground oauth2 also you can test the above stuff by selecting Admin SDK API directory_v1 and auth/admin.directory.user.readonly to authorize the respective scope, then call the above requests.
Note that, you may need to get access to google playground within your google admin dashboard under the security apps section.
You need to specify either the domain (to get fields from only one domain) or the customer (to return all domains for a customer account).
I filed a bug to make more clear that is required to provide one of the two parameters.
At the very least, you need to include the Content-Type header:
curl -X GET -H "Content-Type: application/json" https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&access_token=<Token>
For a full script that implements this API with CURL and BASH see this answer.
Note that the documentation is currently incorrect because it lists customer as an optional parameter when it is in fact required.

Categories

Resources