TWILIO CHAT : what am i doing wrong in getting members online update - twilio

I initialize the chat client using chat token .
i have two members in each channel . I want to know whether the user online or not.
For that in backend i added twilio chat service instance { reachabilityEnabled: true } as the doc says
and in frontend i wrote this code to get memebers information.
var member = await this.myChannel.getMembers();
member.forEach((member)=>{
console.log(member)
member.on('userInfoUpdated', (m)=>{
console.log(m);
})
member.on('updated', (m)=>{ console.log("hey")
console.log(m);
})
})
but in member object i'm not getting any element from that i can check whether is user online or not.
this is response of member object
channel: t {…}
services: e {…}
state: {attributes: {…}, dateCreated: Fri May 15 2020 19:---- (India Standard Time), dateUpdated: Fri May 1------------ (India Standard Time), sid: "MB7545cfa292314570a39385943ac541ad", typingTimeout: null, …}
_events: {updated: Array(2), userInfoUpdated: ƒ}
_eventsCount: 2
_maxListeners: undefined
attributes: (...)
dateCreated: (...)
dateUpdated: (...)
identity: (...)
isTyping: (...)
lastConsumedMessageIndex: (...)
lastConsumptionTimestamp: (...)
roleSid: (...)
sid: (...)
type: (...)
Please suggest me some way how will i do it because i'm stuck here very badly .
if you need more code or information about this flow let me know but please suggest me some way. because there are question for this concern on any platform so from where i can clear it .

Member and User are similar yet different objects. I believe your looking for the User resource to determine the IsOnline status.
After fetching your members; you can then use the members Identity to perform a user fetch which will give you that users IsOnline status.
See: Twilio User support docs.

Related

Neo4j GraphQL auth directive always giving forbidden

I'm trying to implement the #auth directive in GraphQL for use with Neo4j as documented here:
https://neo4j.com/docs/graphql-manual/current/auth/auth-directive/
With a jwt token that is taken from firebase, and should have all of the necessary fields, including admin roles
The problem is that whenever I try to use one of the generated queries with the admin bearer token it says "forbidden" when the auth directive is attached to it.
The full discussion of this issue between me and ChatGPT, which includes extensive trial and error that was done before writing this question, logs, code snippets etc, can be found here for reference:
https://firebasestorage.googleapis.com/v0/b/awtsmoos.appspot.com/o/ai%2FBH_1674546675630.html?alt=media&token=17b653c4-5db2-4bca-8bc1-3cc3625e5a6c
Just to summarize some key code parts, I'm trying to follow the setup example like this essentially:
const neoSch = new graphqlNeo.Neo4jGraphQL({
typeDefs: typeDefs,
driver:dr,
resolvers:rez,
plugins: {
auth: new neoGraphQLAuth
.Neo4jGraphQLAuthJWTPlugin({
secret:
secret.private_key.toString()
})
}
})
Here's the schema that it suggested after I gave it some samples, doesn't work:
type Homework {
id: ID #id
title: String!
steps: [Step!]! #relationship(
type: "HAS",
direction: OUT
)
}
extend type Homework #auth(
rules:[
{
allow: CREATE,
roles:[
"ADMIN"
]
}
]
)
extend type Homework #auth(
rules:[
{
allow: READ,
}
]
)
The token itself is getting properly passed in, as discussed at length in the ChatGPT session, I'm not sure what else it is?
Where the secret property is my JSON of a service account taken from firebase, then in my Apollo context I've tried lots of trial and error with no success, in this matter, but here was one implantation I tried:
app.use(
"/etsem",
cors(),
bodyp.json(),
exp4.expressMiddleware(
serv, {
context: async info => {
var rz = {
req:info.req,
headers:info.req.headers
}
return rz;
}
}
)
)
But still I got the forbidden error

Create team from group fails with exception

I created teams in Microsoft Teams (from groups as documented here) via the C# graph-api sdk without any problems - everything was working just fine.
But suddenly this is not working anymore. I will always get the following exception at the line return await graphServiceClient.Teams.Request().AddAsync(team);:
Message: Failed to execute Templates backend request
CreateTeamFromGroupWithTemplateRequest. Request Url:
https://teams.microsoft.com/fabric/emea/templates/api/groups/theGroupId/team,
Request Method: PUT,
And further:
Team Visibility can not be specified as it is inherited from the
group.
I know that the visibility property must not be set if creating the team from a group as it states in the Microsoft documentation:
The team that's created will always inherit from the group's display name, visibility, specialization, and members. Therefore, when making this call with the group#odata.bind property, the inclusion of team displayName, visibility, specialization, or members#odata.bind properties will return an error.
But the currently used code below shows that I am not setting any forbidden properties - and this code worked for the last few days, too:
private async Task<Team> CreateTeamFromGroup(string groupId)
{
var graphServiceClient = [...]
var groupResourceLink = $"https://graph.microsoft.com/v1.0/groups('{groupId}')";
var team = new Team
{
AdditionalData = new Dictionary<string, object>()
{
{ "template#odata.bind", "https://graph.microsoft.com/beta/teamsTemplates('standard')" },
{ "group#odata.bind", groupResourceLink }
},
Channels = new TeamChannelsCollectionPage
{
new Channel
{
DisplayName = "WhatEver"
}
}
};
return await graphServiceClient.Teams.Request().AddAsync(team);
}
Is anyone else experiencing this problem? Was there an API change? Was the teams backend changed? Anyone any ideas?
P.S.: I am using the latest NuGet-Package for Microsoft Graph - downgrading didn't help.
Update (with a not very satisfying work-around)
The error can be reproduced via the graph api explorer, too.
The POST command above issues a PUT command, that is described here. With this request, the team can be created.
The documentation and the graph api snippet for C# is out-dated, though. You have to add odatatype = null to the properties when using the sdk
Unfortunately it is not possible to add channels in the same step. If you specify the property 'channels' it will just be ignored.
Update (Detailed error message)
System.AggregateException: 'One or more errors occurred. (Code:
BadRequest Message: Failed to execute Templates backend request
CreateTeamFromGroupWithTemplateRequest. Request Url:
https://teams.microsoft.com/fabric/emea/templates/api/groups/theGroupId/team,
Request Method: PUT, Response Status Code: BadRequest,
ErrorMessage : {"errors":[{"message":"Team Visibility can not be
specified as it is inherited from the
group."}],"operationId":"639448e414ece64caee8f52839585bf7"} Inner
error: AdditionalData: date: 2020-11-24T10:21:22 request-id:
37a28cac-3ac5-4bd2-a061-daf44c442fac client-request-id:
37a28cac-3ac5-4bd2-a061-daf44c442fac ClientRequestId:
37a28cac-3ac5-4bd2-a061-daf44c442fac )'
Just tested this morning and I can say, that the "old way" by using the beta API to create a team with a template works again. Don't know, how many other ways exist to do these things, but here is our current request, that works now (again).
POST https://graph.microsoft.com/beta/teams
{
"displayName": "My Group Name",
"description": "Some description",
"template#odata.bind": "https://graph.microsoft.com/beta/teamsTemplates('educationClass')",
"owners#odata.bind": [
"https://graph.microsoft.com/beta/users('<someValidUserId>')"
]
}
I think this will be just an intermediate state and when the bugs are fixed, they will publish the new version again and this kind of creation will fail again, but if in this case the v1.0 documented way will work this wouldn't be a big problem. But being informed BEFORE there roll-out starts would be great.
This was a Microsoft issue/ bug and is currently being fixed as stated here.

Microsoft Teams Graph API - Invalid bind property name owners in request

I'm currently having major issues with creating teams from the Graph API. I was initially trying to create teams based on groups, however I have found out today that you can now create a team without creating a group first then waiting 15 minutes to then create the team from the following link. This would make things considerably simpler.
https://learn.microsoft.com/en-us/graph/api/team-post?view=graph-rest-1.0
I am using the Microsoft.Graph SDK (v3.12.0 released 26th Aug) so replicated the http call using the SDK as follows.
var team = new Team
{
DisplayName = "My Group Name",
Description = "My Group Description",
AdditionalData = new Dictionary<string, object>()
{
{"template#odata.bind", "https://graph.microsoft.com/v1.0/teamsTemplates('educationClass')"},
{"owners#odata.bind", $"[\"https://graph.microsoft.com/v1.0/users('{usersGuid}')\"]"}
},
};
var response = await _graphClient.Teams
.Request()
.AddAsync(team);
The code above gives a:
[16:14:01 ERR] An unhandled exception has occurred while executing the request.
Status Code: BadRequest
Microsoft.Graph.ServiceException: Code: BadRequest
Message: Invalid bind property name owners in request.
If I remove the line
{"owners#odata.bind", $"[\"https://graph.microsoft.com/v1.0/users('{usersGuid}')\"]"}
from the code I get the following:
ErrorMessage : {"errors":[{"message":"A team owner must be provided when creating a team in application context."}]
Any advice would be greatly appreciated.
Thanks,
Nick
In v1.0 the owners relationship is not currently present, so you have to use the beta endpoint.
POST: https://graph.microsoft.com/beta/teams
with the following body format
{ "template#odata.bind":"https://graph.microsoft.com/beta/teamsTemplates('standard')", "displayName":"Test Team", "description":"Test description", "owners#odata.bind":["https://graph.microsoft.com/v1.0/users/{user guid}"] }
Note: the user guid should also be bare, i.e without the brackets and quotes in your example.

Is there a way to link the Google Identity Token to my company user in the database?

I'm setting up an action on google project which uses the OAuth & Google Sign In Linking Type.
Previously, I was using the userId that was sent in every request to look up the user in the database to see if there were accesstokens and refreshtokens available. But since userId is deprecated, I am looking for an alternative.
The user starts his/her dialog and then bumps into this piece of code:
app.intent('Give Color', async (conv, { color }) => {
conv.data[Fields.COLOR] = color;
if (conv.user.ref) {
await conv.user.ref.set({ [Fields.COLOR]: color });
conv.close(`I got ${color} as your favorite color.`);
return conv.close('Since you are signed in, I\'ll remember it next time.');
}
return conv.ask(new SignIn(`To save ${color} as your favorite color for next time`));
});
The "To continue, link Test App to your Google Account" on which the user selects the correct Google account.Then my /token endpoint is called on the OAuth server containing the Google ID Token (assertion) which holds all of the users data. I decode it, check in the database if the "sub" is already present, and I throw the following exception:
return res.status(401).send({ error: 'user_not_found' });
Then the normal OAuth procedure kicks in, where I deliver a token to Google. Sidenote: this is my own OAuth Server written in NodeJS. I am sure that the access- and refreshtoken are delivered to Google.
After token delivery, I get a new request on my action:
app.intent('Get Sign In', async (conv, params, signin) => {
if (signin.status !== 'OK') {
return conv.close('Let\'s try again next time.');
}
const color = conv.data[Fields.COLOR];
await conv.user.ref.set({ [Fields.COLOR]: color });
return conv.close(`I saved ${color} as your favorite color. `
+ 'Since you are signed in, I\'ll remember it next time.');
});
The signin.status has a value of "OK". But shouldn't the conv.user object contain the Google ID Token so that I can store the access- and refreshtoken along with this "sub" from the Google ID Token in my database? Or am I getting something wrong?
The content of the conv.user looks like this:
User {raw: Object, storage: Object, _id: undefined, locale: "en-BE", verification: "VERIFIED", …}
_id: undefined
[[StableObjectId]]: 7
access: Access {token: "ACCT-ATlbRmcpMI545WJFssRSlK1Jcza46NIB"}
entitlements: Array(0) []
id: undefined
last: Last {seen: Thu Aug 08 2019 10:53:17 GMT+0200 (Central Europea…}
locale: "en-BE"
name: Name {display: undefined, family: undefined, given: undefined}
permissions: Array(0) []
profile: Profile {token: undefined}
raw: Object {accessToken: "ACCT-ATlbRmcpMI545WJFssRSlK1Jcza46NIB", locale: "en-BE", lastSeen: "2019-08-08T08:53:17Z", …}
storage: Object {}
verification: "VERIFIED"
__proto__: Object {constructor: , _serialize: , _verifyProfile: , …}
conv.user.id is *DEPRECATED*: Use conv.user.storage to store data instead
It won't contain the Google ID of the user, because the user hasn't authorized that.
What they have authorized is whatever you've asked them to authorize via your OAuth server.
So you'll see the access token that your server has sent to the Assistant in conv.user.access, and you can then use this token to lookup who the user is in your database and take action accordingly.
If you specifically want their Google ID, you'll need to make sure that they use Google Sign-In on the same project as your Action (either through voice, a mobile app, or a webapp).
If you just need an ID so you can see when this user returns later, you can use the Google ID you get from Google Sign-In, or just generate an ID and store this in conv.user.storage.
Since I just want to have an ID, I will be using this:
If you just need an ID so you can see when this user returns later, you can use the Google ID you get from Google Sign-In, or just generate an ID and store this in conv.user.storage.
Thanks!

jwt authentication in iOS client nodejs server via third party authenticator

I am trying to wrap my head around using json webtoken (jwt) based authentication on a server coupled to using a third party (say google) to authenticate the user. Originally I've managed to build my own login and jwt handling scheme with jsonwebtoken on my nodejs server, but we need a client running on an iOS system to interact with it and started looking around for a solution where we don't have to code so much client code (requesting new token when expired etc.) and thought that we would use a third party library to do this for us.
The thing is I did not find anything that would do this for us. I found libraries that could handle connecting the client to a google api for the client, I found user identification handled by google, but didn't find anything that would handle actually getting a jwt that the server would except as a genuine user.
My question is essentially this: we have an iOS client and a nodejs server and would like to use google to authenticate our users and have the client call api-s on our nodejs server, with as much of the authentication process handled by some third party library (google's?), how should we get around to this?
As a note, I've seen passport but that seems to operate with sessions only, and I would have to solve the jwt handling by myself were I to use that.
The iOS part is not ready, but I managed to use google to authenticate and authorize without a session in the browser. The idea is, that the client logs in to google (see here for web app) and google graciously also gives you a token with the login, which will be good for the server. On the nodejs side I used passport and the google-id-token strategy (see on github). There are quite a few strategies for google out there, but this one works. Although, this has a shortcoming, it can't accept the token in the header, but I fixed that in a pull request (see here).
Since I had a bit of a problem of how to use the User.findOrCreate part of all the passport examples, I'll put in my code here that covers a full working example:
var passport = require('passport');
var GoogleTokenStrategy = require(passport-google-id-token)
passport.use(new GoogleTokenStrategy({
clientID: config.googleAuth.clientID,
clientSecret: config.googleAuth.clientSecret,
},
function(parsedToken, googleId, done) {
console.log(parsedToken);
console.log(googleId);
User.findOne({ 'google.id': googleId }, function (err, user) {
if (!user) {
var testuser = new User({
name: parsedToken.payload.name,
givenName : parsedToken.payload.givenName,
familyName : parsedToken.payload.familyName,
nameunderscore : parsedToken.payload.name.split(' ').join("_"),
admin: false,
email: parsedToken.payload.email,
settings: {save_folder:"default"},
'google.id' : googleId,
'google.email' : parsedToken.payload.email,
});
testuser.save(function(err) {})
}
return done(err, user);
});
}
));
User comes from mongodb in a separate js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('User', new Schema({
name: String,
nameunderscore : String,
givenName: String,
familyName: String,
admin: Boolean,
settings: {
save_folder: String
},
email: String,
google: {
id: String,
email: String
}
}));
And this is how I added the passport strategy to a router (note that session is set to false):
var apiRoutes = express.Router();
apiRoutes.use(passport.authenticate('google-id-token',{ session: false }));
Now every call to any route in apiRoutes must send on id_token with a valid google token to get access.

Resources