I'm trying to create a gist on github.com using the user ID. Currently I can create anonymous gist with the node-github module.
This is the code
github.gists.create({
"description": "the description for this gist",
"public": true,
"files": {
"BONE101TEST_2.md": {
"content": "<html><h1>This is a Test!</h1><b>Hello</b><img src=></html>"
}
}
}, function(err, rest) {
console.log(rest);
});
According to the github documentation " to read or write gists on a user’s behalf the gist OAuth scope is required." This will give me the tokens for the user.
But how do I specify that I want that the gist has to be created using the user X. I'm reading the node-githu documentation but doesn't tells me this. Any idea?
Updated
I can create a programatic token according to the docs. Still not sure how to identify the id of the user for creating the gist, if the create method doesn't make reference to it.
github.authorization.create({
scopes: ["user", "public_repo", "repo", "repo:status", "gist"],
note: "what this auth is for",
note_url: "http://url-to-this-auth-app",
headers: {
"X-GitHub-OTP": "two-factor-code"
}
}, function(err, res) {
if (res.token) {
//save and use res.token as in the Oauth process above from now on
}
});
In one of the links you share with me had the answer. Just modify it.
Here's the code if someone needs it.
http.createServer(function(req, res) {
var url = Url.parse(req.url);
var path = url.pathname;
var query = querystring.parse(url.query);
if (path == "/" || path.match(/^\/user\/?$/)) {
// redirect to github if there is no access token
if (!accessToken) {
res.writeHead(303, {
Location: oauth.getAuthorizeUrl({
redirect_uri: 'http://localhost:3000/github-callback',
scope: "user,repo,gist"
})
});
res.end();
return;
}
// use github API
github.gists.create({
"description": "the description for this gist",
"public": true,
"files": {
"TEST_2.md": {
"content": "<html><h1>This is a Test!</h1><b>Hello</b><img src=></html>"
}
}
}, function(err, rest) {
console.log(rest);
});
return;
}
// URL called by github after authenticating
else if (path.match(/^\/github-callback\/?$/)) {
// upgrade the code to an access token
oauth.getOAuthAccessToken(query.code, {}, function (err, access_token, refresh_token) {
if (err) {
console.log(err);
res.writeHead(500);
res.end(err + "");
return;
}
accessToken = access_token;
// authenticate github API
github.authenticate({
type: "oauth",
token: accessToken
});
//redirect back
res.writeHead(303, {
Location: "/"
});
res.end();
});
return;
}
res.writeHead(404);
res.end("404 - Not found");
}).listen(3000);
Related
The file is shared success and the shared user gets an email notification, file display in the user google drive but when we try using API to get shared files, it is not working.
var SCOPES = ["https://www.googleapis.com/auth/drive.file", "profile"];
function createPermissions(fileId, body) {
gapi.client.load("drive", "v3", function() {
gapi.client.drive.permissions
.create({
fileId: fileId,
resource: body
})
.then(function(res) {
//console.log(res);
Swal.fire("Success!", "File has been success shared!", "success");
// do something
})
.catch(function(err) {
//console.log(err);
Swal.fire({
icon: "error",
title: "Oops...",
text: "Something went wrong! Plese try agian later!!",
footer: ""
});
// do something
});
});
}
The above code is working fine, the file is successfully shared but when shared user login in-app user can't access shared files.
Anyone please suggest/help to fix the above issue?
Thanks
I would suggest you call the Drive API in this way:
// This is a good scope for testing
const SCOPES = ["https://www.googleapis.com/auth/drive"];
// This code takes into consideration that you already did all the OAuth2.0 proccess
// correctly to connect to the Drive API
module.exports.init = async function (){
// Create the Drive service
const drive = google.drive({version: 'v3', oauth2Client});
// Create permissions for an user
await createPermissions(drive, null, null);
}
// This function will create the permissions to share a file using Promises
function createPermissions(drive, fileId, body){
// These parameters are for test, past the values you want as arguments
fileId = fileId || "your-file-id";
body = body || {
"role": "writer",
"type": "user",
"emailAddress": "user#domain"
};
// Create the promise and return the value from the promise if you want to
return new Promise((resolve, reject) => {
try {
// Call the endpoint, if there are no errors you will pass the results to resolve
// to return them as the value from your promise
return drive.permissions.create({
fileId: fileId,
resource: body
},
(err, results) => {
if(err) reject(`Drive error: ${err.message}`);
resolve(results);
});
} catch (error) {
console.log(`There was a problem in the promise: ${error}`);
}
});
}
I tried it and the files are shared successfully to the user I wanted. Keep in mind to build your body as:
{
"role": "writer",
"type": "user",
"emailAddress": "user#domain"
};
Docs
Here are some links to know more about the Drive API Permissions:
Permissions.
Permissions: create.
i can't get the Credentials for my CognitoIdentity. When the User is successfully authenticated, he needs to get a Identity to access other AWS Services. In my case thats AWS IoT. But for somehow, i can't get any credentials.
This is the Error Message:
Error retrieving credentials: NotAuthorizedException: Access to
Identity 'eu-central-1:XXXXXXXXXX' is
forbidden.
My Code is almost exactly like the Tutorial on Github:
var cognitoUser = new AWSCognito.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
console.log("Logged in");
console.log('access token + ' + result.getAccessToken().getJwtToken());
// window.location.href = "index.html";
AWS.config.region = AWSConfiguration.region;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: AWSConfiguration.IdPoolId,
Logins : {
'cognito-idp.eu-central-1.amazonaws.com/eu-central-1_XXXX' : result.getIdToken().getJwtToken()
}
});
var cognitoIdentity = new AWS.CognitoIdentity();
AWS.config.credentials.get(function(err, data) {
if (!err) {
console.log('retrieved identity: ' + AWS.config.credentials.identityId);
var params = {
IdentityId: AWS.config.credentials.identityId
};
cognitoIdentity.getCredentialsForIdentity(params, function(err, data) {
if (!err) {
thingShadows.updateWebSocketCredentials(data.credentials.AccessKeyId,
data.credentials.SecretKey,
data.credentials.SessionToken);
}
else {
console.log('error retrieving credentials: ' + err);
}
});
}
else {
console.log('error retrieving identity:' + err);
}
});
}
});
Please note that i skipped not related code.
authenticated users have full access to all AWS services i'm using.
I don't think you need to call cognitoIdentity.getCredentialsForIdentity(). Your IAM keys should be put into the AWS.config.credentials object when you call AWS.config.credentials.get(). You can access them directly in the callback you provide when you call it.
In other words, when you're logging out the retrieved identity: to the console, the credentials object should already have your secret key, access key id, and session token in it.
All of this (give or take a curly brace):
var params = {
IdentityId: AWS.config.credentials.identityId
};
cognitoIdentity.getCredentialsForIdentity(params, function(err, data) {
if (!err) {
thingShadows.updateWebSocketCredentials(data.credentials.AccessKeyId,
data.credentials.SecretKey,
data.credentials.SessionToken);
}
else {
console.log('error retrieving credentials: ' + err);
}
});
Can probably be replaced with something like this:
thingShadows.updateWebSocketCredentials(AWS.config.credentials.accessKeyId,
AWS.config.credentials.secretKey,
AWS.config.credentials.sessionToken);
If you pass in a Logins map with the user pool id and access token in it, the getCredentialsForIdentity() call might succeed; I didn't test it. I haven't yet run into a use case where I needed to use this particular API, and I suspect you don't need it either.
Source: I work on a 100% javascript application that uses both authenticated and unauthenticated Cognito identities. We don't call getCredentialsForIdentity() anywhere, and trying to insert it produced the same error you're getting.
I'm building a web app with the MEAN Stack. What I am trying to achieve is that when the user logs in his user information get fetched by Angular from my REST API. I set up the API route http://localhost:3000/api/user/profile which should respond with json including the user object.
router.get('/user/profile', function(req, res, next){
//console.log(req);
if(req.user === undefined){
res.json({
success: false,
msg: 'Unautorized'
});
} else {
res.json({
success: true,
user: {
id: req.user.steam.id,
name: req.user.steam.name,
avatar: req.user.steam.avatar,
avatarmedium: req.user.steam.avatarmedium,
avatarfull: req.user.steam.avatarfull
}
});
}
});
When the user logs in Angular start a GET-Request:
ngOnInit() {
this.authService.getProfile().subscribe(profile => {
this.user = profile.user;
console.log(profile);
},
err => {
console.log(err);
return false;
});
}
getProfile():
getProfile(){
return this.http.get('http://localhost:3000/api/user/profile')
.map(res => res.json());
}
When I load up my site, log in, and go to the profile page the returned object contains success: false and the message 'Unauthorized' instead of the user object. Why is this happening?
I completely redesigned my approach. I implemented json web token which now sends a token (containing all user data) to the user through a url parameter once he signs in.
I have authorised a small node app with the gmail API. I am successfully getting responses. I can, for eg, see my email signature using users.settings.sendAs.list()
However When I try and make a change to the settings, again in this case the signature, the response I get back is empty. So the update is working in so far as i can wipe a signature I added manually in gmail, but I cannot add anything new.
Here's the script
var google = require('googleapis');
var key = require('./Sig-Updater.json');
var gmail = google.gmail('v1');
var jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
['https://www.googleapis.com/auth/gmail.settings.basic', 'https://www.googleapis.com/auth/gmail.settings.sharing', 'https://www.googleapis.com/auth/gmail.modify', 'https://mail.google.com', 'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.readonly' ],
'some_email#somewhere.com'
);
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log('Auth failed because: ' + err);
return;
}
console.log(tokens)
gmail.users.settings.sendAs.update({
userId: 'me',
auth: jwtClient,
sendAsEmail: 'some_email#somewhere.com',
signature: '<div dir="ltr">Hello there</div>'
}, function (err, resp) {
if(err){
console.log(err);
} else {
console.log(resp);
}
});
});
Sorry for any noob business - new to this API and indeed node.js
Looks like my Noob disclaimer was warranted in the end,
I had omitted the 'resource' object from the request.
Should look more like
gmail.users.settings.sendAs.update({
userId: 'me',
auth: jwtClient,
sendAsEmail: 'some_email#somewhere.com',
fields: 'signature',
resource: {
signature: '<div dir="ltr">Hello there</div>'
}
}, function (err, resp) {
if(err){
console.log(err);
} else {
console.log(resp);
}
});
Hope that helps someone in the future!
I am building a project using Deployd for assistance with my API, and dpd-passport for authentication.
I seem to have everything authenticating, with session keys behind handed out and users authentication through Google, but I am having trouble with my redirectURLs, as well as translating the callback page I am returned with.
I have dug into the dpd-passport/index.js file, and I believe this is the relevant information:
var sendResponse = function(ctx, err, config) {
var sessionData = ctx.session.data;
var returnUrl = (ctx.req.cookies && ctx.req.cookies.get('_passportReturnUrl')) || null;
if(returnUrl) {
var redirectURL = url.parse(returnUrl, true);
// only append if not disabled
if(!config.disableReturnParams) {
// delete search so that query is used
delete redirectURL.search;
// make sure query is inited
redirectURL.query = redirectURL.query || {};
if(err) {
redirectURL.query.success = false;
redirectURL.query.error = err;
} else {
// append user + session id to the redirect url
redirectURL.query.success = true;
if(!config.disableSessionId) {
redirectURL.query.sid = sessionData.id;
redirectURL.query.uid = sessionData.uid;
}
}
}
var redirectURLString = '';
try {
redirectURLString = url.format(redirectURL);
} catch(ex) {
console.warn('An error happened while formatting the redirectURL', ex);
}
// redirect the user
ctx.res.setHeader("Location", redirectURLString);
ctx.res.statusCode = 302;
ctx.done(null, 'This page has moved to ' + redirectURLString);
} else {
if(err) {
ctx.res.statusCode = 401;
console.error(err);
return ctx.done('bad credentials');
} else {
ctx.done(err, { path: sessionData.path, id: sessionData.id, uid: sessionData.uid });
}
}
};
After successfully authenticating, I am given a returnUrl of:
http://localhost:3000/auth/google/callback?code=4/l4o-H2F4QKJ5tdKbVbGfWygTGRvhHgr9zrHWImFFKdM#
with an body of:
{"path":"/users","id":"d03c0faccfe41134c193266afef979c5af33adf935aeff45844b0f9473dee4ab1fbd1114240e13ea9a542785da3845cfec984e3a5b8cb188d6c595b6fc39a726","uid":"747f97a9bcfa9811"}
which seems to me like my results are hitting the final else statement in the topmost code block.
If this is true, then my returnUrl is NULL.
Tracing back the returnUrl code in the dpd-passport file, it looks like it should be grabbing this from cookies in the follow snippet:
if(ctx.query.redirectURL && this.config.allowedRedirectURLs) {
try {
this.regEx = this.regEx || new RegExp(this.config.allowedRedirectURLs, 'i');
if(ctx.query.redirectURL.match(this.regEx)) {
// save this info into the users session, so that we can access it later (even if the user was redirected to facebook)
if (ctx.res.cookies) ctx.res.cookies.set('_passportReturnUrl', ctx.query.redirectURL);
} else {
debug(ctx.query.redirectURL, 'did not match', this.config.allowedRedirectURLs);
}
} catch(ex) {
debug('Error parsing RedirectURL Regex!', ex);
}
}
To add to this, I have my allowedRedirectUrls in the config as:
^http://localhost:3000/.*$
I am at a loss and am hoping there is something obvious that I am missing.
I have seen the passport routes and authentication strategies similar to the following, but have been unsuccessful in implementing this into dpd-passport:
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
To add to this all, I am using ui-router/AngularJS.
You have to supply the redirectURL to dpd-passport through the link that starts the oauth procedure:
http://localhost:2403/auth/google?redirectURL=http://localhost