JsonWebToken encode is undefined - javascript

I'm creating my first ever login system, using JsonWebTokens, and I've hit an obstacle trying to use the encode function.
My error message says:
if (this.ended && !this.hasRejectListeners()) throw reason;
^ TypeError: undefined is not a function
and I've managed to narrow the error down to this line of code:
var jwt = require('jsonwebtoken');
jwt.encode(payload, superSecret);
The function this is a part of looks like this:
var moment = require('moment');
var jwt = require('jsonwebtoken');
var superSecret = require('../config/token.js').secret;
function (user) {
var payload = {
sub: user._id,
iat: moment().unix(),
exp: moment().add(14, 'days').unix()
};
return = jwt.encode(payload, superSecret);
Needless to say, since this is the first time I'm authenticating anything, I don't know why this would cause an error. Please help.

Related

How to connect Wix Answers to my SSO server

I made a makeshift 'sso server' which I want to connect to Wix Answers. Wix is a CMS. Wix Answers is a help center where you can customer FAQs, have customers receive support videos, and the customer can enter tickets. Wix answers are what Wix uses for Wix's help pages and they make the same app available to users for the same purpose.
My 'sso server' is an AWS API Gateway pointing to a Lambda function. Pretty straight forward. You call the public endpoint and it runs this lambda:
var express = require('express');
var app = express();
var crypto = require('crypto'); //npm install crypto --save
var base64url = require('base64url'); //npm install base64url --save
var bodyParser = require('body-parser');
var KEY_ID = '1234567'; //note it's a uuid
var SECRET = '1234567xxxxxxxxxxxxxxxxxxxxxxxxxxx';
exports.handler = async (event) => {
//this assumes there is a login or some UI that will receive the needed redirect url
app.get('/login-form', function (request, response) {
var url = require('url');
var urlParts = url.parse(request.url, true);
var query = urlParts.query;
var answersRedirectUrl = query.redirectUrl;
//of course, in a real system the data will come from your own user system
var dummyUserData = {
id: 'your-user-id',
email: 'user#email.com',
firstName: 'Bob2',
lastName: 'Bobson',
profileImage: 'https://i.ytimg.com/vi/-90CAdWk27I/maxresdefault.jpg',
timestamp: Date.now()
};
var token = encryptUserData(JSON.stringify(dummyUserData), SECRET);
response.redirect(answersRedirectUrl + '&token=' + token + '&key=' + KEY_ID);
});
};
function encryptUserData(data, key) {
var iv = new Buffer('');
var bytes = new Buffer(key, 'utf-8');
var hashedKey = crypto.createHash('sha1').update(bytes).digest().slice(0, 16);
var cipher = crypto.createCipheriv('aes-128-ecb', hashedKey, iv);
var crypted = cipher.update(data, 'UTF-8', 'hex');
crypted += cipher.final('hex');
return base64url(new Buffer(crypted, 'hex'));
}
This code is a lambda modified version of the code Wix Answers sample js code from, here.
https://help.wixanswers.com/en/article/setting-up-single-sign-on-sso-for-your-users
There are dependencies, and I have loaded them all into a lambda, so its not a dependency issue.
Wix Answers is an easy setup, you give them a url for login and logout. you generate a key inside of Wix answers dashboard, and I have added that key to my lambda below (the ones below are masked obviously). I've added my endpoint to the field in wix answers.
I'm getting a null response and was able to get an object with object.message = "missing auth token"
Focusing on the JS and the lambda, is there anything that I am leaving out that would make this not work. Again not a lot of experience with express and these dependencies, or with SSO.
Thanks!!
Wix Has some good tools but lacks documentation sometimes. Here is how I solved this problem:
tutorial https://help.wixanswers.com/en/article/setting-up-single-sign-on-sso-for-your-users
their JS code from https://gist.github.com/GabiGrin/0c92ecbb071e02e2d91c8d689517acd7#file-answers-sso-example-js
What I did
//encrypt.js
var crypto = require('crypto'); //built in to node
var base64url = require('base64url'); //requires install 'npm install base64url'
var KEY_ID = 'abcedfghijklmnopqrstuvwxyz'; //from Wix Answers
var SECRET = 'fakefakefakefakefakefake'; //from Wix Answers
let user = {
id: '123456',
email: 'email#domain.com',
firstName: 'Homer',
lastName: 'Simpson',
profileImage: 'https://i.ytimg.com/vi/-90CAdWk27I/maxresdefault.jpg',
timestamp: Date.now()
};
function encryptUserData(data, key) {
var iv = new Buffer('');
var bytes = new Buffer(key, 'utf-8');
var hashedKey = crypto.createHash('sha1').update(bytes).digest().slice(0, 16);
var cipher = crypto.createCipheriv('aes-128-ecb', hashedKey, iv);
var crypted = cipher.update(data, 'UTF-8', 'hex');
crypted += cipher.final('hex');
return base64url(new Buffer(crypted, 'hex'));
}
var token = encryptUserData(JSON.stringify(user), SECRET);
console.log(`https://mysite.wixanswers.com/api/v1/accounts/callback/sso?redirectUrl=https%3A%2F%2Fmysite.wixanswers.com%2Fen&token=${token}&key=${KEY_ID}`);
Since my project is a concept, I have not integrated with a real identity server, as you can see i skip the authentication and go right to authorization (for my hard coded user: Homer Simpson). To mkae it work i'd need to add authentication and pass a dynamic user object to an export function in the module.
for the sake of the concept tho:
from the shell 'node encrypt.js'
returns a redirect URL in the console - when followed, successfully signs you into the Wix Answers platform with the proper user object.

Verify Token generated in C# with System.IdentityModel.Tokens.Jwt

I have created a token like this in my web api with C#.
private const string Secret = "someSecretKey";
public static string GenerateToken(AuthModel user, int expireMinutes = 20)
{
var symmetricKey = Convert.FromBase64String(Secret);
var tokenHandler = new JwtSecurityTokenHandler();
var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.Role, ((Roles)user.RoleId).ToString()),
new Claim("guid",user.Guid)
}),
Expires = now.AddMinutes(Convert.ToInt32(expireMinutes)),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature)
};
var stoken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(stoken);
return token;
}
and when im usin that API for reactjs app i get the token but cant verify it with same secret key.
Im getting error INVALID SIGNATURE.
Im using jsonwebtoken npm package,
import jwt from 'jsonwebtoken';
jwt.verify(token, keys.jwtSecret, async (err) => {
if (err) {
//console.log('Token expired at: ', err.expiredAt)
console.log("error", err)
}
else {
dispatch(login(token));
}
});
i never hit that dispatch(login(token)). I'm using this to check if token saved in localStorage is still valid to keep user signed in.
Any help is appreciated.
I've found solution. Couldn't just push secretKey in jwt.verify(token,secretKey); That doesn't work because some base64 encoding/decoding algorithms. What i had to do is first to make a Buffer from my secret like:
const secret = new Buffer("myTokeSecretString", "base64");
and then pass that secret to verify method and it works.

json data extract nested objects from _body - Javascript

I am trying to get value of a token but I get error ERROR TypeError: Cannot read property 'token' of undefined
code
//Below code gives the output shown below with black color text
data.text()
// I am interested in fetching token value which is nested inside success keyword, below code fails to get the token
var abc = data.text();
abc['success'].token
let abc = JSON.parse(data.text());
var abc = (JSON.parse(data._body)).success.token;
Following code is for reading JWT form js
function parseJwt (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace('-', '+').replace('_', '/');
return JSON.parse(window.atob(base64));
};
How to decode jwt token in javascript

415 Unsupported Media Type error - Domo Connector

So I'm building a connector using the Domo developer tool (they like to call it an IDE) and I just can't seem to get the authentication piece working with their libraries.
Domo uses httprequest library for basic and oauth types of authentication.
I'm having trouble getting token back through Domo, but I can easily do it through a curl or by using the Postman api tool.
Here's the code below:
var client_id = '4969e1ea-71b9-3267-ae7d-4ce0ac6bfa28';
var client_secret = '*****************************';
var user = '*********';
var pass = '*********';
var postData =
{
data: {
'grant_type': 'password',
'username': user,
'password': pass,
'client_id': client_id,
'client_secret': client_secret,
'scope': 'internal'
}
};
var res = httprequest.post('https://rest.synthesio.com/security/v1/oauth/token', postData);
DOMO.log('res: ' + res);
Pleae let me know if you have a different way of approaching this. I've tried to add the header within the postData object itself as well as removing the data variable, leaving the attributes as is, too.
When you past the postData as an object like that, DOMO will run it through JSON.stringify and send the result in the request body.
You can either encode the request body manually or use their httprequest.addParameter function to add them. Try something like this:
var client_id = '4969e1ea-71b9-3267-ae7d-4ce0ac6bfa28';
var client_secret = '*****************************';
var user = '*********';
var pass = '*********';
httprequest.addParameter('grant_type', 'password');
httprequest.addParameter('username', user);
httprequest.addParameter('password', pass);
httprequest.addParameter('client_id', client_id);
httprequest.addParameter('client_secret', client_secret);
httprequest.addParameter('scope', 'internal');
var res = httprequest.post('https://rest.synthesio.com/security/v1/oauth/token');
DOMO.log('res: ' + res);

Node.js - how to use external library (VersionOne JS SDK)?

I'm trying to use VersionOne JS SDK in Node.js (https://github.com/versionone/VersionOne.SDK.JavaScript). I'm simply downloading whole library, placing it alongside with my js file:
var v1 = require('./v1sdk/v1sdk.js');
var V1Server = v1.V1Server;
console.log(v1);
console.log(V1Server);
Unfortunately something seems wrong, the output I get after calling
node app.js
is:
{}
undefined
Can somebody point me what I'm doing wrong or check whether the sdk is valid.
Thanks!
You can see in the source where V1Server is defined, that it's a class with a constructor. So you need to use the new keyword and pass the arguments for your environment.
https://github.com/versionone/VersionOne.SDK.JavaScript/blob/master/client.coffee#L37
var server = new V1Server('cloud'); //and more if you need
Can you try the sample.js script that I just updated from here:
https://github.com/versionone/VersionOne.SDK.JavaScript/blob/master/sample.js
It pulls in the two modules like this:
var V1Meta = require('./v1meta').V1Meta;
var V1Server = require('./client').V1Server;
var hostname = "www14.v1host.com";
var instance = "v1sdktesting";
var username = "api";
var password = "api";
var port = "443";
var protocol = "https";
var server = new V1Server(hostname, instance, username, password, port, protocol);
var v1 = new V1Meta(server);
v1.query({
from: "Member",
where: {
IsSelf: 'true'
},
select: ['Email', 'Username', 'ID'],
success: function(result) {
console.log(result.Email);
console.log(result.Username);
console.log(result.ID);
},
error: function(err) { // NOTE: this is not working correctly yet, not called...
console.log(err);
}
});
You might have to get the latest and build the JS from CoffeeScript.
I think I was trying out "browserify" last year and that's how the "v1sdk.js" file got generated. But I'm not sure if that's the best approach if you're using node. It's probably better just to do it the way the sample.js file is doing it.
However, I did also check in a change to v1sdk.coffee which property exports the two other modules, just as a convenience. With that, you can look at sample2.js. The only different part there is this, which is more like you were trying to do with your example:
var v1sdk = require('./v1sdk');
var hostname = "www14.v1host.com";
var instance = "v1sdktesting";
var username = "api";
var password = "api";
var port = "443";
var protocol = "https";
var server = new v1sdk.V1Server(hostname, instance, username, password, port, protocol);
var v1 = new v1sdk.V1Meta(server);

Categories

Resources