How to set the templateUrl in a component in Angular2? - asp.net-mvc

How can I set the templateUrl in code? E.g., if I have
#Component({
selector: 'search-load',
templateUrl: '/loads/search'
})
I want:
#Component({
selector: 'search-load',
templateUrl: this.language+ 'loads/search'
})
where templateUrl is a mvc path.
Thank you.

You cannot this in component declaration like this since its outside of component's scope but this is how I do something like this
In my component:
#Component({
selector: 'live-auction-stats',
templateUrl: BaseConfigurations.baseTemplatePath + '/auction-stats.html',
})
And In my BaseConfigurations.ts file, I have
export abstract class BaseConfigurations
{
public baseTemplatePath: string = location.origin + '/app/templates'; //you can configure here
....
//other base configurations..
....
}

After a long searching i found that node_modules\#angular\platform-browser-dynamic\bundles\platform-browser-dynamic.umd.js is the responsible for loading template by url
so i can add some params to url dynamically like this :
var lang = JSON.parse(localStorage.getItem("Accept-Language"));
xhr.open('GET', lang+url, true);
then the final file will be :
(function(System, SystemJS) {/**
* #license Angular v2.2.3
* (c) 2010-2016 Google, Inc. https://angular.io/
* License: MIT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('#angular/compiler'), require('#angular/core'), require('#angular/platform-browser')) :
typeof define === 'function' && define.amd ? define(['exports', '#angular/compiler', '#angular/core', '#angular/platform-browser'], factory) :
(factory((global.ng = global.ng || {}, global.ng.platformBrowserDynamic = global.ng.platformBrowserDynamic || {}),global.ng.compiler,global.ng.core,global.ng.platformBrowser));
}(this, function (exports,_angular_compiler,_angular_core,_angular_platformBrowser) { 'use strict';
var INTERNAL_BROWSER_PLATFORM_PROVIDERS = _angular_platformBrowser.__platform_browser_private__.INTERNAL_BROWSER_PLATFORM_PROVIDERS;
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var ResourceLoaderImpl = (function (_super) {
__extends(ResourceLoaderImpl, _super);
function ResourceLoaderImpl() {
_super.apply(this, arguments);
}
ResourceLoaderImpl.prototype.get = function (url) {
var resolve;
var reject;
var promise = new Promise(function (res, rej) {
resolve = res;
reject = rej;
});
var xhr = new XMLHttpRequest();
var lang = JSON.parse(localStorage.getItem("Accept-Language"));
xhr.open('GET', lang+url, true);
xhr.responseType = 'text';
xhr.onload = function () {
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in ResourceLoader Level2 spec (supported
// by IE10)
var response = xhr.response || xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
var status = xhr.status === 1223 ? 204 : xhr.status;
// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : 0;
}
if (200 <= status && status <= 300) {
resolve(response);
}
else {
reject("Failed to load " + url);
}
};
xhr.onerror = function () { reject("Failed to load " + url); };
xhr.send();
return promise;
};
ResourceLoaderImpl.decorators = [
{ type: _angular_core.Injectable },
];
/** #nocollapse */
ResourceLoaderImpl.ctorParameters = [];
return ResourceLoaderImpl;
}(_angular_compiler.ResourceLoader));
var INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS = [
INTERNAL_BROWSER_PLATFORM_PROVIDERS,
{
provide: _angular_core.COMPILER_OPTIONS,
useValue: { providers: [{ provide: _angular_compiler.ResourceLoader, useClass: ResourceLoaderImpl }] },
multi: true
},
];
/**
* #license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var globalScope;
if (typeof window === 'undefined') {
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
// TODO: Replace any with WorkerGlobalScope from lib.webworker.d.ts #3492
globalScope = self;
}
else {
globalScope = global;
}
}
else {
globalScope = window;
}
// Need to declare a new variable for global here since TypeScript
// exports the original value of the symbol.
var _global = globalScope;
// TODO: remove calls to assert in production environment
// Note: Can't just export this and import in in other files
// as `assert` is a reserved keyword in Dart
_global.assert = function assert(condition) {
// TODO: to be fixed properly via #2830, noop for now
};
/**
* #license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var __extends$1 = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/**
* An implementation of ResourceLoader that uses a template cache to avoid doing an actual
* ResourceLoader.
*
* The template cache needs to be built and loaded into window.$templateCache
* via a separate mechanism.
*/
var CachedResourceLoader = (function (_super) {
__extends$1(CachedResourceLoader, _super);
function CachedResourceLoader() {
_super.call(this);
this._cache = _global.$templateCache;
if (this._cache == null) {
throw new Error('CachedResourceLoader: Template cache was not found in $templateCache.');
}
}
CachedResourceLoader.prototype.get = function (url) {
if (this._cache.hasOwnProperty(url)) {
return Promise.resolve(this._cache[url]);
}
else {
return Promise.reject('CachedResourceLoader: Did not find cached template for ' + url);
}
};
return CachedResourceLoader;
}(_angular_compiler.ResourceLoader));
var __platform_browser_dynamic_private__ = {
INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS: INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
ResourceLoaderImpl: ResourceLoaderImpl
};
/**
* #experimental
*/
var RESOURCE_CACHE_PROVIDER = [{ provide: _angular_compiler.ResourceLoader, useClass: CachedResourceLoader }];
/**
* #stable
*/
var platformBrowserDynamic = _angular_core.createPlatformFactory(_angular_compiler.platformCoreDynamic, 'browserDynamic', INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
exports.RESOURCE_CACHE_PROVIDER = RESOURCE_CACHE_PROVIDER;
exports.platformBrowserDynamic = platformBrowserDynamic;
exports.__platform_browser_dynamic_private__ = __platform_browser_dynamic_private__;
}));
})(System, System);

Related

node-config change delimiter from dot to colon

Im migrating my config from another library to node-config.
I have two questions:
The old library uses config.get('a:b'); to get some value, but node-config use a single dot as a delimiter: config.get('a.b');.
Is there is a way to configure it to use : to save my time and refactor my code?
Is there is a way to set a runtime values. e.g. config.set('key', 'val');?
Done it by:
1. wrap node-config in a new js file
2. proxied the get, has and set methods methods
Something like that:
const config = require('config');
const inMemDict = {};
const toNewKey = key => {
return key && key.split(':').join('.');
};
const { get: origGet, has: origHas } = config;
config.get = function (key, ...args) {
key = toNewKey(key);
if(typeof inMemDict[key] !== 'undefined') {
return inMemDict[key];
}
return origGet.apply(config, [key, ...args]);
};
config.has = function (key, ...args) {
key = toNewKey(key);
if(typeof inMemDict[key] !== 'undefined') {
return inMemDict[key];
}
return origHas.apply(config, [key, ...args]);
};
config.set = function (key, val) {
if(!key) return;
inMemDict[toNewKey(key)] = val;
};
module.exports = config;

Is it possible to get Google Ouath2 access token without setting a redirect URI?

I am trying to implement Google Oauth2 consent screen within a popup but it says redirect URI mismatch. Is there any way where I can set up a web Ouath Client App without setting redirect uri in the dashboard?
I know setting up client type from web to others or application may solve this issue. But I want to implement it for web type only. Is this possible?
<!DOCTYPE html>
<html>
<head>
<script>
'use strict';
var GO2 = function GO2(options) {
if (!options || !options.clientId) {
throw 'You need to at least set the clientId';
}
if (typeof window != 'undefined'){
this._redirectUri = window.location.href.substr(0,
window.location.href.length -
window.location.hash.length)
.replace(/#$/, '');
}
// Save the client id
this._clientId = options.clientId;
// if scope is an array, convert it into a string.
if (options.scope) {
this._scope = Array.isArray(options.scope) ?
options.scope.join(' ') :
options.scope;
}
// rewrite redirect_uri
if (options.redirectUri) {
this._redirectUri = options.redirectUri;
}
// popup dimensions
if (options.popupHeight) {
this._popupHeight = options.popupHeight;
}
if (options.popupWidth) {
this._popupWidth = options.popupWidth;
}
if (options.responseType) {
this._responseType = options.responseType;
}
if (options.accessType) {
this._accessType = options.accessType;
}
};
GO2.receiveMessage = function GO2_receiveMessage() {
var go2;
if (window.opener && window.opener.__windowPendingGO2) {
go2 = window.opener.__windowPendingGO2;
}
if (window.parent && window.parent.__windowPendingGO2) {
go2 = window.parent.__windowPendingGO2;
}
var hash = window.location.hash;
if (go2 && hash.indexOf('access_token') !== -1) {
go2._handleMessage(
hash.replace(/^.*access_token=([^&]+).*$/, '$1'),
parseInt(hash.replace(/^.*expires_in=([^&]+).*$/, '$1'), 10),
hash.replace(/^.*state=go2_([^&]+).*$/, '$1')
);
}
if (go2 && window.location.search.indexOf('code=')) {
go2._handleMessage(
window.location.search.replace(/^.*code=([^&]+).*$/, '$1'),
null,
window.location.search.replace(/^.*state=go2_([^&]+).*$/, '$1')
);
}
if (go2 && window.location.search.indexOf('error=')) {
go2._handleMessage(false);
}
};
GO2.prototype = {
WINDOW_NAME: 'google_oauth2_login_popup',
OAUTH_URL: 'https://accounts.google.com/o/oauth2/v2/auth',
_clientId: undefined,
_scope: 'https://www.googleapis.com/auth/plus.me',
_redirectUri: '',
_popupWindow: null,
_immediateFrame: null,
_stateId: Math.random().toString(32).substr(2),
_accessToken: undefined,
_timer: undefined,
_popupWidth: 500,
_popupHeight: 400,
_responseType: 'token',
_accessType: 'online',
onlogin: null,
onlogout: null,
login: function go2_login(forceApprovalPrompt, immediate) {
if (this._accessToken) {
return;
}
this._removePendingWindows();
window.__windowPendingGO2 = this;
var url = this.OAUTH_URL +
'?response_type=' + this._responseType +
'&access_type='+ encodeURIComponent(this._accessType) +
'&redirect_uri=' + encodeURIComponent(this._redirectUri) +
'&scope=' + encodeURIComponent(this._scope) +
'&state=go2_' + this._stateId +
'&client_id=' + encodeURIComponent(this._clientId);
console.log(url);
if (!immediate && forceApprovalPrompt) {
url += '&approval_prompt=force';
}
if (immediate) {
url += '&approval_prompt=auto';
// Open up an iframe to login
// We might not be able to hear any of the callback
// because of X-Frame-Options.
var immediateFrame =
this._immediateFrame = document.createElement('iframe');
immediateFrame.src = url;
immediateFrame.hidden = true;
immediateFrame.width = immediateFrame.height = 1;
immediateFrame.name = this.WINDOW_NAME;
document.body.appendChild(immediateFrame);
return;
}
// Open the popup
var left =
window.screenX + (window.outerWidth / 2) - (this._popupWidth / 2);
var top =
window.screenY + (window.outerHeight / 2) - (this._popupHeight / 2);
var windowFeatures = 'width=' + this._popupWidth +
',height=' + this._popupHeight +
',top=' + top +
',left=' + left +
',location=no,toolbar=no,menubar=no';
this._popupWindow = window.open(url, this.WINDOW_NAME, windowFeatures);
},
logout: function go2_logout() {
if (!this._accessToken) {
return;
}
this._removePendingWindows();
clearTimeout(this._timer);
this._accessToken = undefined;
if (this.onlogout) {
this.onlogout();
}
},
getAccessToken: function go2_getAccessToken() {
return this._accessToken;
},
// receive token from popup / frame
_handleMessage: function go2_handleMessage(token, expiresIn, stateId) {
if (this._stateId !== stateId) {
return;
}
this._removePendingWindows();
// Do nothing if there is no token received.
if (!token) {
return;
}
this._accessToken = token;
if (this.onlogin) {
this.onlogin(this._accessToken);
}
if (expiresIn) {
// Remove the token if timed out.
clearTimeout(this._timer);
this._timer = setTimeout(
function tokenTimeout() {
this._accessToken = undefined;
if (this.onlogout) {
this.onlogout();
}
}.bind(this),
expiresIn * 1000
);
}
},
destory: function go2_destory() {
if (this._timer) {
clearTimeout(this._timer);
}
this._removePendingWindows();
},
_removePendingWindows: function go2_removePendingWindows() {
if (this._immediateFrame) {
document.body.removeChild(this._immediateFrame);
this._immediateFrame = null;
}
if (this._popupWindow) {
this._popupWindow.close();
this._popupWindow = null;
}
if (window.__windowPendingGO2 === this) {
delete window.__windowPendingGO2;
}
}
};
// if the context is the browser
if (typeof window !== 'undefined') {
// If the script loads in a popup matches the WINDOW_NAME,
// we need to handle the request instead.
if (window.name === GO2.prototype.WINDOW_NAME) {
GO2.receiveMessage();
}
}
// Expose the library as an AMD module
if (typeof define === 'function' && define.amd) {
define('google-oauth2-web-client', [], function () { return GO2; });
} else if (typeof module === 'object' && typeof require === 'function') {
// export GO2 in Node.js, assuming we are being browserify'd.
module.exports = GO2;
if (require.main === module) {
console.error('Error: GO2 is not meant to be executed directly.');
}
} else {
window.GO2 = GO2;
}
function test(){
var go2 = new GO2({
clientId: 'dfsdffdfgsfsdfggdgd.apps.googleusercontent.com',
redirectUri: 'http://localhost:8888/gapi/test.html',
responseType: 'code',
accessType: 'offline'
});
go2.login();
}
</script>
</head>
<body>
<a href='#' onClick='test();'> Click here to login </a>
</body>
</html>
It looks like you're using the implicit grant type which requires a redirect uri with response_type=token.
Can you use the authorization code grant type?
The redirect uri is optional for the authorization code grant type.
https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1

How to print called functions in android?

I'm using frida on an APK and I'm trying to print out which function is being called, and especially which parameters are sent to it. My environment is set correctly as I can print out classes, and perform various actions in accordance to the docs.
This is the closest i've found:
https://codeshare.frida.re/#razaina/get-a-stack-trace-in-your-hook/
But the code gives out errors (ThreadDef undefined and so on)
And the frida docs didn't help me get where I'm trying to.
Any guidance? suggestions? help?
The code from codeshare#razaina has bugs which can be easily fixed (threadef != ThreadDef)
var printBacktrace = function () {
Java.perform(function() {
var JLog = Java.use('android.util.Log'), JException = Java.use('java.lang.Exception');
// getting stacktrace by throwing an exception
console.warn(JLog.getStackTraceString(JException.$new()));
});
};
Just call printBacktrace() w/e you want to see who called your hooked function.
If you want to hook all the methods of Java class you can use this snippet;
var Color = {
RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", Green: "2;01", Purple: "5;01", Red: "1;01", Yellow: "3;01",
Light: {
Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", Green: "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11"
}
};
/**
*
* #param input.
* If an object is passed it will print as json
* #param kwargs options map {
* -l level: string; log/warn/error
* -i indent: boolean; print JSON prettify
* -c color: #see ColorMap
* }
*/
var LOG = function (input, kwargs) {
kwargs = kwargs || {};
var logLevel = kwargs['l'] || 'log', colorPrefix = '\x1b[3', colorSuffix = 'm';
if (typeof input === 'object')
input = JSON.stringify(input, null, kwargs['i'] ? 2 : null);
if (kwargs['c'])
input = colorPrefix + kwargs['c'] + colorSuffix + input + Color.RESET;
console[logLevel](input);
};
var printBacktrace = function () {
Java.perform(function() {
var android_util_Log = Java.use('android.util.Log'), java_lang_Exception = Java.use('java.lang.Exception');
// getting stacktrace by throwing an exception
LOG(android_util_Log.getStackTraceString(java_lang_Exception.$new()), { c: Color.Gray });
});
};
function traceClass(targetClass) {
var hook;
try {
hook = Java.use(targetClass);
} catch (e) {
console.error("trace class failed", e);
return;
}
var methods = hook.class.getDeclaredMethods();
hook.$dispose();
var parsedMethods = [];
methods.forEach(function (method) {
var methodStr = method.toString();
var methodReplace = methodStr.replace(targetClass + ".", "TOKEN").match(/\sTOKEN(.*)\(/)[1];
parsedMethods.push(methodReplace);
});
uniqBy(parsedMethods, JSON.stringify).forEach(function (targetMethod) {
traceMethod(targetClass + '.' + targetMethod);
});
}
function traceMethod(targetClassMethod) {
var delim = targetClassMethod.lastIndexOf('.');
if (delim === -1)
return;
var targetClass = targetClassMethod.slice(0, delim);
var targetMethod = targetClassMethod.slice(delim + 1, targetClassMethod.length);
var hook = Java.use(targetClass);
var overloadCount = hook[targetMethod].overloads.length;
LOG({ tracing: targetClassMethod, overloaded: overloadCount }, { c: Color.Green });
for (var i = 0; i < overloadCount; i++) {
hook[targetMethod].overloads[i].implementation = function () {
var log = { '#': targetClassMethod, args: [] };
for (var j = 0; j < arguments.length; j++) {
var arg = arguments[j];
// quick&dirty fix for java.io.StringWriter char[].toString() impl because frida prints [object Object]
if (j === 0 && arguments[j]) {
if (arguments[j].toString() === '[object Object]') {
var s = [];
for (var k = 0, l = arguments[j].length; k < l; k++) {
s.push(arguments[j][k]);
}
arg = s.join('');
}
}
log.args.push({ i: j, o: arg, s: arg ? arg.toString(): 'null'});
}
var retval;
try {
retval = this[targetMethod].apply(this, arguments); // might crash (Frida bug?)
log.returns = { val: retval, str: retval ? retval.toString() : null };
} catch (e) {
console.error(e);
}
LOG(log, { c: Color.Blue });
return retval;
}
}
}
// remove duplicates from array
function uniqBy(array, key) {
var seen = {};
return array.filter(function (item) {
var k = key(item);
return seen.hasOwnProperty(k) ? false : (seen[k] = true);
});
}
var Main = function() {
Java.perform(function () { // avoid java.lang.ClassNotFoundException
[
// "java.io.File",
'java.net.Socket',
'com.package.MyCustomClass'
].forEach(traceClass);
});
};
Java.perform(Main);

Netsuite OAuth Not Working

I've tried implementing Netsuite's OAuth Example, as illustrated here: https://netsuite.custhelp.com/app/answers/detail/a_id/42165. I've posted it directly below so you don't have to go to the page if you don't want.
Unfortunately, it's not working. I know that I have the correct token and consumer key's and secrets, and the correct account ID. It's giving me a nice error though:
{"error" : {"code" : "INVALID_LOGIN_ATTEMPT", "message" : "Invalid login attempt."}}
I can look in my login audits, and see that it's saying that the signature is invalid. But the code itself looks fine and was provided by Netsuite.
I've also tried some approaches in Node.JS and haven't gotten them working. Any suggestions as to which direction I should go next?
import oauth2 as oauth
import requests
import time
url = "https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5", secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38", secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "GET"
realm="ACCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
req = oauth.Request(method=http_method, url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
headery = header['Authorization'].encode('ascii', 'ignore')
headerx = {"Authorization": headery, "Content-Type":"application/json"}
print(headerx)
conn = requests.get("https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1",headers=headerx)
print(conn.text)
I've also implemented a few Node.JS samples (that haven't worked either). Here is one of them (CryptoJS HMAC-SHA1 and HMAC-SHA256 are on top, then the oauth-1.0a library, and then the code provided by Netsuite with a few small changes to make it work (added a hash_function, renamed 'public' to 'key'):
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(g,l){var e={},d=e.lib={},m=function(){},k=d.Base={extend:function(a){m.prototype=this;var c=new m;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
p=d.WordArray=k.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=l?c:4*a.length},toString:function(a){return(a||n).stringify(this)},concat:function(a){var c=this.words,q=a.words,f=this.sigBytes;a=a.sigBytes;this.clamp();if(f%4)for(var b=0;b<a;b++)c[f+b>>>2]|=(q[b>>>2]>>>24-8*(b%4)&255)<<24-8*((f+b)%4);else if(65535<q.length)for(b=0;b<a;b+=4)c[f+b>>>2]=q[b>>>2];else c.push.apply(c,q);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=g.ceil(c/4)},clone:function(){var a=k.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b<a;b+=4)c.push(4294967296*g.random()|0);return new p.init(c,a)}}),b=e.enc={},n=b.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++){var d=c[f>>>2]>>>24-8*(f%4)&255;b.push((d>>>4).toString(16));b.push((d&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f+=2)b[f>>>3]|=parseInt(a.substr(f,
2),16)<<24-4*(f%8);return new p.init(b,c/2)}},j=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++)b.push(String.fromCharCode(c[f>>>2]>>>24-8*(f%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f++)b[f>>>2]|=(a.charCodeAt(f)&255)<<24-8*(f%4);return new p.init(b,c)}},h=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(j.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return j.parse(unescape(encodeURIComponent(a)))}},
r=d.BufferedBlockAlgorithm=k.extend({reset:function(){this._data=new p.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,b=c.words,f=c.sigBytes,d=this.blockSize,e=f/(4*d),e=a?g.ceil(e):g.max((e|0)-this._minBufferSize,0);a=e*d;f=g.min(4*a,f);if(a){for(var k=0;k<a;k+=d)this._doProcessBlock(b,k);k=b.splice(0,a);c.sigBytes-=f}return new p.init(k,f)},clone:function(){var a=k.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});d.Hasher=r.extend({cfg:k.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){r.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,d){return(new a.init(d)).finalize(b)}},_createHmacHelper:function(a){return function(b,d){return(new s.HMAC.init(a,
d)).finalize(b)}}});var s=e.algo={};return e}(Math);
(function(){var g=CryptoJS,l=g.lib,e=l.WordArray,d=l.Hasher,m=[],l=g.algo.SHA1=d.extend({_doReset:function(){this._hash=new e.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(d,e){for(var b=this._hash.words,n=b[0],j=b[1],h=b[2],g=b[3],l=b[4],a=0;80>a;a++){if(16>a)m[a]=d[e+a]|0;else{var c=m[a-3]^m[a-8]^m[a-14]^m[a-16];m[a]=c<<1|c>>>31}c=(n<<5|n>>>27)+l+m[a];c=20>a?c+((j&h|~j&g)+1518500249):40>a?c+((j^h^g)+1859775393):60>a?c+((j&h|j&g|h&g)-1894007588):c+((j^h^
g)-899497514);l=g;g=h;h=j<<30|j>>>2;j=n;n=c}b[0]=b[0]+n|0;b[1]=b[1]+j|0;b[2]=b[2]+h|0;b[3]=b[3]+g|0;b[4]=b[4]+l|0},_doFinalize:function(){var d=this._data,e=d.words,b=8*this._nDataBytes,g=8*d.sigBytes;e[g>>>5]|=128<<24-g%32;e[(g+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(g+64>>>9<<4)+15]=b;d.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=d.clone.call(this);e._hash=this._hash.clone();return e}});g.SHA1=d._createHelper(l);g.HmacSHA1=d._createHmacHelper(l)})();
(function(){var g=CryptoJS,l=g.enc.Utf8;g.algo.HMAC=g.lib.Base.extend({init:function(e,d){e=this._hasher=new e.init;"string"==typeof d&&(d=l.parse(d));var g=e.blockSize,k=4*g;d.sigBytes>k&&(d=e.finalize(d));d.clamp();for(var p=this._oKey=d.clone(),b=this._iKey=d.clone(),n=p.words,j=b.words,h=0;h<g;h++)n[h]^=1549556828,j[h]^=909522486;p.sigBytes=b.sigBytes=k;this.reset()},reset:function(){var e=this._hasher;e.reset();e.update(this._iKey)},update:function(e){this._hasher.update(e);return this},finalize:function(e){var d=
this._hasher;e=d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e))}})})();
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(h,s){var f={},g=f.lib={},q=function(){},m=g.Base={extend:function(a){q.prototype=this;var c=new q;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
r=g.WordArray=m.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||k).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push(4294967296*h.random()|0);return new r.init(c,a)}}),l=f.enc={},k=l.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b,
2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}},
u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;g<a;g+=e)this._doProcessBlock(d,g);g=d.splice(0,a);c.sigBytes-=b}return new r.init(g,b)},clone:function(){var a=m.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});g.Hasher=u.extend({cfg:m.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){u.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new t.HMAC.init(a,
d)).finalize(c)}}});var t=f.algo={};return f}(Math);
(function(h){for(var s=CryptoJS,f=s.lib,g=f.WordArray,q=f.Hasher,f=s.algo,m=[],r=[],l=function(a){return 4294967296*(a-(a|0))|0},k=2,n=0;64>n;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]=
c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes;
d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math);
(function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j<h;j++)k[j]^=1549556828,n[j]^=909522486;r.sigBytes=l.sigBytes=m;this.reset()},reset:function(){var f=this._hasher;f.reset();f.update(this._iKey)},update:function(f){this._hasher.update(f);return this},finalize:function(f){var g=
this._hasher;f=g.finalize(f);g.reset();return g.finalize(this._oKey.clone().concat(f))}})})();
//oauth-1.0a
if (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') {
module.exports = OAuth;
}
/**
* Constructor
* #param {Object} opts consumer key and secret
*/
function OAuth(opts) {
if(!(this instanceof OAuth)) {
return new OAuth(opts);
}
if(!opts) {
opts = {};
}
if(!opts.consumer) {
throw new Error('consumer option is required');
}
this.consumer = opts.consumer;
this.nonce_length = opts.nonce_length || 32;
this.version = opts.version || '1.0';
this.parameter_seperator = opts.parameter_seperator || ', ';
this.realm = opts.realm;
if(typeof opts.last_ampersand === 'undefined') {
this.last_ampersand = true;
} else {
this.last_ampersand = opts.last_ampersand;
}
// default signature_method is 'PLAINTEXT'
this.signature_method = opts.signature_method || 'PLAINTEXT';
if(this.signature_method == 'PLAINTEXT' && !opts.hash_function) {
opts.hash_function = function(base_string, key) {
return key;
}
}
if(!opts.hash_function) {
throw new Error('hash_function option is required');
}
this.hash_function = opts.hash_function;
this.body_hash_function = opts.body_hash_function || this.hash_function;
}
/**
* OAuth request authorize
* #param {Object} request data
* {
* method,
* url,
* data
* }
* #param {Object} key and secret token
* #return {Object} OAuth Authorized data
*/
OAuth.prototype.authorize = function(request, token) {
var oauth_data = {
oauth_consumer_key: this.consumer.key,
oauth_nonce: this.getNonce(),
oauth_signature_method: this.signature_method,
oauth_timestamp: this.getTimeStamp(),
oauth_version: this.version
};
if(!token) {
token = {};
}
if(token.key !== undefined) {
oauth_data.oauth_token = token.key;
}
if(!request.data) {
request.data = {};
}
if(request.includeBodyHash) {
oauth_data.oauth_body_hash = this.getBodyHash(request, token.secret)
}
oauth_data.oauth_signature = this.getSignature(request, token.secret, oauth_data);
return oauth_data;
};
/**
* Create a OAuth Signature
* #param {Object} request data
* #param {Object} token_secret key and secret token
* #param {Object} oauth_data OAuth data
* #return {String} Signature
*/
OAuth.prototype.getSignature = function(request, token_secret, oauth_data) {
return this.hash_function(this.getBaseString(request, oauth_data), this.getSigningKey(token_secret));
};
/**
* Create a OAuth Body Hash
* #param {Object} request data
*/
OAuth.prototype.getBodyHash = function(request, token_secret) {
var body = typeof request.data === 'string' ? request.data : JSON.stringify(request.data)
if (!this.body_hash_function) {
throw new Error('body_hash_function option is required');
}
return this.body_hash_function(body, this.getSigningKey(token_secret))
};
/**
* Base String = Method + Base Url + ParameterString
* #param {Object} request data
* #param {Object} OAuth data
* #return {String} Base String
*/
OAuth.prototype.getBaseString = function(request, oauth_data) {
return request.method.toUpperCase() + '&' + this.percentEncode(this.getBaseUrl(request.url)) + '&' + this.percentEncode(this.getParameterString(request, oauth_data));
};
/**
* Get data from url
* -> merge with oauth data
* -> percent encode key & value
* -> sort
*
* #param {Object} request data
* #param {Object} OAuth data
* #return {Object} Parameter string data
*/
OAuth.prototype.getParameterString = function(request, oauth_data) {
var base_string_data;
if (oauth_data.oauth_body_hash) {
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.deParamUrl(request.url))));
} else {
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.mergeObject(request.data, this.deParamUrl(request.url)))));
}
var data_str = '';
//base_string_data to string
for(var i = 0; i < base_string_data.length; i++) {
var key = base_string_data[i].key;
var value = base_string_data[i].value;
// check if the value is an array
// this means that this key has multiple values
if (value && Array.isArray(value)){
// sort the array first
value.sort();
var valString = "";
// serialize all values for this key: e.g. formkey=formvalue1&formkey=formvalue2
value.forEach((function(item, i){
valString += key + '=' + item;
if (i < value.length){
valString += "&";
}
}).bind(this));
data_str += valString;
} else {
data_str += key + '=' + value + '&';
}
}
//remove the last character
data_str = data_str.substr(0, data_str.length - 1);
return data_str;
};
/**
* Create a Signing Key
* #param {String} token_secret Secret Token
* #return {String} Signing Key
*/
OAuth.prototype.getSigningKey = function(token_secret) {
token_secret = token_secret || '';
if(!this.last_ampersand && !token_secret) {
return this.percentEncode(this.consumer.secret);
}
return this.percentEncode(this.consumer.secret) + '&' + this.percentEncode(token_secret);
};
/**
* Get base url
* #param {String} url
* #return {String}
*/
OAuth.prototype.getBaseUrl = function(url) {
return url.split('?')[0];
};
/**
* Get data from String
* #param {String} string
* #return {Object}
*/
OAuth.prototype.deParam = function(string) {
var arr = string.split('&');
var data = {};
for(var i = 0; i < arr.length; i++) {
var item = arr[i].split('=');
// '' value
item[1] = item[1] || '';
// check if the key already exists
// this can occur if the QS part of the url contains duplicate keys like this: ?formkey=formvalue1&formkey=formvalue2
if (data[item[0]]){
// the key exists already
if (!Array.isArray(data[item[0]])) {
// replace the value with an array containing the already present value
data[item[0]] = [data[item[0]]];
}
// and add the new found value to it
data[item[0]].push(decodeURIComponent(item[1]));
} else {
// it doesn't exist, just put the found value in the data object
data[item[0]] = decodeURIComponent(item[1]);
}
}
return data;
};
/**
* Get data from url
* #param {String} url
* #return {Object}
*/
OAuth.prototype.deParamUrl = function(url) {
var tmp = url.split('?');
if (tmp.length === 1)
return {};
return this.deParam(tmp[1]);
};
/**
* Percent Encode
* #param {String} str
* #return {String} percent encoded string
*/
OAuth.prototype.percentEncode = function(str) {
return encodeURIComponent(str)
.replace(/\!/g, "%21")
.replace(/\*/g, "%2A")
.replace(/\'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29");
};
/**
* Percent Encode Object
* #param {Object} data
* #return {Object} percent encoded data
*/
OAuth.prototype.percentEncodeData = function(data) {
var result = {};
for(var key in data) {
var value = data[key];
// check if the value is an array
if (value && Array.isArray(value)){
var newValue = [];
// percentEncode every value
value.forEach((function(val){
newValue.push(this.percentEncode(val));
}).bind(this));
value = newValue;
} else {
value = this.percentEncode(value);
}
result[this.percentEncode(key)] = value;
}
return result;
};
/**
* Get OAuth data as Header
* #param {Object} oauth_data
* #return {String} Header data key - value
*/
OAuth.prototype.toHeader = function(oauth_data) {
var sorted = this.sortObject(oauth_data);
var header_value = 'OAuth ';
if (this.realm) {
header_value += 'realm="' + this.realm + '"' + this.parameter_seperator;
}
for(var i = 0; i < sorted.length; i++) {
if (sorted[i].key.indexOf('oauth_') !== 0)
continue;
header_value += this.percentEncode(sorted[i].key) + '="' + this.percentEncode(sorted[i].value) + '"' + this.parameter_seperator;
}
return {
Authorization: header_value.substr(0, header_value.length - this.parameter_seperator.length) //cut the last chars
};
};
/**
* Create a random word characters string with input length
* #return {String} a random word characters string
*/
OAuth.prototype.getNonce = function() {
var word_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
var result = '';
for(var i = 0; i < this.nonce_length; i++) {
result += word_characters[parseInt(Math.random() * word_characters.length, 10)];
}
return result;
};
/**
* Get Current Unix TimeStamp
* #return {Int} current unix timestamp
*/
OAuth.prototype.getTimeStamp = function() {
return parseInt(new Date().getTime()/1000, 10);
};
////////////////////// HELPER FUNCTIONS //////////////////////
/**
* Merge object
* #param {Object} obj1
* #param {Object} obj2
* #return {Object}
*/
OAuth.prototype.mergeObject = function(obj1, obj2) {
obj1 = obj1 || {};
obj2 = obj2 || {};
var merged_obj = obj1;
for(var key in obj2) {
merged_obj[key] = obj2[key];
}
return merged_obj;
};
/**
* Sort object by key
* #param {Object} data
* #return {Array} sorted array
*/
OAuth.prototype.sortObject = function(data) {
var keys = Object.keys(data);
var result = [];
keys.sort();
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
result.push({
key: key,
value: data[key],
});
}
return result;
};
//NETSUITE'S RESTLET
function callRESTlet(request, response) {
var remoteAccountID = 'ACCOUNT ID HERE';
var restletUrl = 'https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1';
//user token
var token = {
key: 'ACCESS KEY HERE',
secret: 'ACCESS SECRET HERE'
};
//app credentials
var oauth = OAuth({
consumer: {
key: 'INTEGRATION KEY HERE',
secret: 'INTEGRATION SECRET HERE'
},
signature_method: 'HMAC-SHA1',
hash_function: function(base_string, key)
{
return CryptoJS.HmacSHA1(base_string, key).toString(CryptoJS.enc.Base64);
}
});
var request_data = {
url: restletUrl,
method: 'GET',
data: {}
};
var oauth_data = {
oauth_consumer_key: oauth.consumer.key,
oauth_nonce: oauth.getNonce(),
oauth_signature_method: oauth.signature_method,
oauth_timestamp: oauth.getTimeStamp(),
oauth_version: '1.0',
oauth_token: token.key,
realm: remoteAccountID
};
var headerWithRealm = oauth.toHeader(oauth.authorize(request_data, token));
headerWithRealm.Authorization += ',realm="' + remoteAccountID + '"';
var restResponse = nlapiRequestURL(restletUrl, null, headerWithRealm, null, "GET");
var html = 'Calling: ' +
restletUrl +
'<br><br>' +
'Generated OAuth header:<br>' +
headerWithRealm.Authorization +
'<br><br>' +
'Response:<br>' +
restResponse.getBody()
response.write(html);
}
EDIT: Just published an npm module which should make things easier: https://www.npmjs.com/package/nsrestlet
Was able to get some code working after hunting through GitHub Code commits. Still, bknights response is really good.
Here's what I got working.
Assuming you have Node.js and npm installed, run:
npm install request
npm install oauth-1.0a#1.0.1
It's really important that it's version 1.0.1.
Once you have that, this code should work:
/*
================= REQUIRED USER ACCOUNT INFORMATION ==============================================
*/
var accountID = 'PUT ACCOUNT ID HERE';
var token = {
public: 'PUT TOKEN KEY HERE',
secret: 'PUB TOKEN SECRET HERE'
};
var consumer = {
public: 'PUT CONSUMER KEY HERE',
secret: 'PUT CONSUMER SECRET HERE'
};
//use the full restlet URL, not the rest.netsuite.com URL
//for example, https://YOURACCOUNTNUMBER.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=SCRIPTNUMBER&deploy=DEPLOYNUMBER
var restlet_url = 'PUT YOUR RESTLET URL HERE';
/*
=========================================================================================================
*/
//REQUIRED NPM MODULES
const request = require('request');
const OAuth = require('oauth-1.0a'); //version 1.0.1, don't do version 1.1.0
//SET UP THE OAUTH OBJECT
var oauth = OAuth({
consumer: consumer,
signature_method: 'HMAC-SHA256' //you can also use HMAC-SHA1 but HMAC-SHA256 is more secure (supposedly)
});
//SET UP THE REQUEST OBJECT
var request_data = {
url: restlet_url,
method: 'POST',
};
//GET THE AUTHORIZATION AND STICK IT IN THE HEADER, ALONG WITH THE REALM AND CONTENT-TYPE
var authorization = oauth.authorize(request_data, token);
var header = oauth.toHeader(authorization);
header.Authorization += ', realm="' + accountID + '"';
header['content-type'] = 'application/json';
//MAKE THE REQUEST
request({
url: request_data.url,
method: request_data.method,
headers: header,
json: {
message: "test123" //this is your payload
}
}, function(error, response, body) {
if(error)
{
console.log(error);
}
else
{
console.log(body);
}
});
If anybody has any problems with this code, leave a response and I'll do my best to help.
Netsuite's node samples use oauth-1.0a
https://netsuite.custhelp.com/app/answers/detail/a_id/42171
and their sample from https://netsuite.custhelp.com/app/answers/detail/a_id/42172/
is what I've had in production for a couple of years and works well.
var Promise = require('bluebird');
var request = require('request');
var crypto = require('crypto');
var OAuth = require('oauth-1.0a');
var Agent = require('https').Agent;
//var debug = require('debug')('kotn-ns');
function promiseTry(pSrc, maxTries, minDelay, maxDelay, canRetry){ //NS prone to spurious failures due to overloading
return new Promise(function(resolve, reject){
minDelay = minDelay || 0;
var delaySize = maxDelay - minDelay;
var t = function(){ return Math.floor(Math.random()* delaySize)+ minDelay;};
var firstReason = null;
function doRetry(triesLeft){
pSrc().then(function(data){
resolve(data);
}).catch(function(reason){
if(!firstReason) firstReason = reason;
console.error('in retry error with '+reason.toString());
if(triesLeft && canRetry(reason)) setTimeout(function(){ doRetry(triesLeft-1);}, t());
else reject(firstReason);
});
}
doRetry(maxTries -1);
});
}
function hasReason(msg, reasons){
for(var i = 0; i< reasons.length;i++){
if(msg.indexOf(reasons[i]) != -1) return true;
}
return false;
}
var agentPool = {};
function getAgent(accountId, tokenId){
var agentKey = accountId+'::'+ tokenId;
var agent = agentPool[agentKey];
if(!agent){
console.log('new agent for '+agentKey)
agent = new Agent({
keepAlive:false,
maxSockets:5
});
agentPool[agentKey] = agent;
}
return agent;
}
/**
* [RESTHandler description]
* #param {options} options {accountId, consumerKey,consumerSecret,tokenId,tokenSecret}
*/
function RESTHandler(options) {
var config = Object.assign({
maxTries:3,
minRetryDelay: 800,
maxRetryDelay:30000,
canRetry: function(reason){
var reasonText = reason.message || JSON.stringify(reason);
if(hasReason(reasonText, ['ECONNRESET', 'ESOCKETTIMEDOUT','ETIMEDOUT', 'SSS_REQUEST_LIMIT_EXCEEDED'])) {
console.error('retrying because: '+reasonText);
return true;
}
console.error('no retry with: '+reasonText);
return false;
}
}, options);
var oauth = OAuth({
consumer: {
key: config.consumerKey,
secret: config.consumerSecret
},
signature_method: 'HMAC-SHA1',
parameter_seperator: ',',
hash_function: function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});
var token = {
key: config.tokenId,
secret: config.tokenSecret
};
function makeRequest(url, method, payload) {
var requestData = {
url: url,
method: method
};
if(payload){
requestData.body = payload;
}
var headers = oauth.toHeader(oauth.authorize(requestData, token));
headers.Authorization += ',realm="' + config.accountId + '"';
headers.authorization = headers.Authorization;
delete headers.Authorization;
headers['content-type'] = 'application/json';
headers['accept'] = 'application/json';
//console.log(JSON.stringify(headers, null, ' '));
requestData.headers = headers;
Object.assign(requestData, {
pool:getAgent(config.accountId, config.tokenId),
timeout : 30000,
strictSSL : true
});
// requestData.json = true;
// return new Promise(function(resolve){
// resolve({'headers' : 'done'});
// });
var processRequest = function(){
return new Promise(function(resolve, reject) {
request(requestData, function(error, response, body) {
if(error){
console.error('error calling: '+ requestData.url);
console.error(error);
reject((error instanceof Error) ? error : new Error(JSON.stringify(error)));
return;
}
if(!body || !(/"success"/).test(body)) {
console.log(method +' '+ response.statusCode +' '+ url +'\n\t'+body);
reject(new Error(body || 'unexpected error'));
return;
}
try{
resolve(JSON.parse(body));
}catch(e){
console.trace(e);
reject(e);
}
});
});
};
return promiseTry(processRequest, config.maxTries, config.maxRetryDelay, config.minRetryDelay, config.canRetry);
}
return{
get: function(url){
return makeRequest(url, 'GET');
},
put: function(url, data){
return makeRequest(url, 'PUT', data);
},
post: function(url, data){
return makeRequest(url, 'POST', data);
},
destroy : function(){
//nsAgent.destroy();
}
};
}
module.exports = RESTHandler;
More up-to-date as of 2022-12-12
replaced request with its successor needle and removed the now unnecessary bluebird
const needle = require('needle');
const crypto = require('crypto');
const OAuth = require('oauth-1.0a');
const Agent = require('https').Agent;
const debug = require('debug')('kotn-nso');
function promiseTry(pSrc, maxTries, minDelay, maxDelay, canRetry){ //NS prone to spurious failures due to overloading
return new Promise((resolve, reject)=>{
minDelay = minDelay || 0;
const delaySize = maxDelay - minDelay;
const t = function(){ return Math.floor(Math.random()* delaySize)+ minDelay;};
let firstReason = null;
function doRetry(triesLeft){
pSrc().then((data)=>{
resolve(data);
}).catch((reason)=>{
if(!firstReason) firstReason = reason;
console.error('in retry error with '+ triesLeft +' for '+reason.toString());
if(triesLeft && canRetry(reason)){
setTimeout(()=>{ doRetry(triesLeft-1);}, t());
}
else reject(firstReason);
});
}
doRetry(maxTries -1);
});
}
function hasReason(msg, reasons){
for(var i = 0; i< reasons.length;i++){
if(msg.indexOf(reasons[i]) != -1) return true;
}
return false;
}
var agentPool = {};
function getAgent(accountId, maxSockets){
var agentKey = accountId+'::'; // + tokenId;
var agent = agentPool[agentKey];
if(!agent){
console.log('new agent for '+agentKey);
agent = new Agent({
keepAlive:false,
maxSockets:maxSockets || 2 // one in reserve for slow closers
});
agentPool[agentKey] = agent;
}
return agent;
}
/**
* [RESTHandler description]
* #param {options} options {accountId, consumerKey,consumerSecret,tokenId,tokenSecret,maxSockets}
*/
function RESTHandler(options) {
const config = Object.assign({
maxTries:3,
minRetryDelay: 400,
maxRetryDelay:30000,
canRetry: function(reason){
var reasonText = reason.message || JSON.stringify(reason);
if(hasReason(reasonText, ['ECONNRESET', 'ESOCKETTIMEDOUT','ETIMEDOUT', 'SSS_REQUEST_LIMIT_EXCEEDED'])) {
console.error('retrying because: '+reasonText);
return true;
}
console.error('no retry with: '+reasonText);
return false;
}
}, options);
const oauth = OAuth({
consumer: {
key: config.consumerKey,
secret: config.consumerSecret
},
signature_method: 'HMAC-SHA256',
parameter_seperator: ',',
hash_function: function(base_string, key) {
return crypto.createHmac('sha256', key).update(base_string).digest('base64');
}
});
const token = {
key: config.tokenId,
secret: config.tokenSecret
};
function makeRequest(url, method, payload) {
debug(method +' '+ JSON.stringify(url));
var requestData = {
url: url,
method: method
};
if(payload){
requestData.body = payload;
}
var headers = oauth.toHeader(oauth.authorize(requestData, token));
headers.Authorization += ',realm="' + config.accountId + '"';
headers.authorization = headers.Authorization;
delete headers.Authorization;
headers['content-type'] = 'application/json';
headers['accept'] = 'application/json';
//console.log(JSON.stringify(headers, null, ' '));
const options = {
headers:headers,
agent:getAgent(config.accountId, config.maxSockets),
timeout : 30000,
strictSSL : true,
time:false
};
var processRequest = function(){
var headers = null;
return needle(method.toLowerCase(), url, payload, options).then(resp=>{
debug(resp.statusCode +' ' + JSON.stringify(resp.headers, null, ' '));
headers = resp.headers;
if(resp.statusCode != 200 && resp.statusCode != 201){
throw new Error(resp.statusCode +': '+ (resp.body || 'unexpected error'));
}
if(!resp.body) throw new Error('Unexpected Response');
return resp.body;
}).catch(error=>{
if(headers){
debug('Error returned with ' + JSON.stringify(headers));
}
const msg = error instanceof Error ? error.message : JSON.stringify(error);
console.error(method +' error on '+ url + ', '+ msg);
throw (error instanceof Error) ? error : new Error(msg);
});
};
return promiseTry(processRequest, config.maxTries, config.maxRetryDelay, config.minRetryDelay, config.canRetry);
}
return{
get: function(url){
return makeRequest(url, 'GET');
},
put: function(url, data){
return makeRequest(url, 'PUT', data);
},
post: function(url, data){
return makeRequest(url, 'POST', data);
},
destroy : function(){
//nsAgent.destroy();
}
};
}
module.exports = RESTHandler;

action script 2.0

Hi I have a small flash as below
public function startApp () : Void
{
mcWindowRoot.refToClass = this;
mcNext = mcWindowRoot;
_oLogoutDelegate = Delegate.create (this, onLogoutHandler);
_oWindowManagerRef.addEventListener ("onLogout", _oLogoutDelegate);
loadWhatNext ();
}
/**
* Enter description here
*
*/
function loadWhatNext (mc : MovieClip) : Void
{
var doneFinish = mcNext.container.attachMovie ("done", "done", mcNext.container.getNextHighestDepth ());
//var returnPage = mcNext.container.attachMovie ("item", "item", mcNext.container.getNextHighestDepth () ,
//{
//_x : 135, _y : 230
//});
var miRefTemp = _oWindowManagerRef;
//returnPage.item_txt.htmlText = _level0.account_Return;
//returnPage.onPress =
doneFinish.onPress = function ()
{
trace ("AccountNext returnPage.onPress doneFinish.onPress" )
trace ("AccountNext miRefTemp " + miRefTemp)
trace ("AccountNext this.refToClass " + this._parent._parent.refToClass)
trace ("AccountNext this " + this)
this._parent._parent.refToClass.closeWindow ();
_oShell.loadWindow( "", null);
}
if (aNextdata != undefined && aNextdata.length > 0)
{
for (var i = 0 ; i < 3; i ++)
{
if (aNextdata [i].text != undefined)
{
var tempItem = mcNext.copy.attachMovie ("item", "item" + i, i,
{
_x : 143, _y : 150 + (i * 20)
});
tempItem.item_txt.htmlText = aNextdata [i].text;
tempItem.url = aNextdata [i].link;
tempItem.refToClass = _refWindow;
var asInterpreter = new asFunctionInterpreter (_oWindowManagerRef._oWindowManagerRef.oController.propertiesMap.get ("BaseURL") , this);
var deepLinks : Object = new Object ();
deepLinks = asInterpreter.getAsSingleURL ( aNextdata [i].link );
tempItem.deepLinks = deepLinks;
trace("Next :: LINKS : " + tempItem.wModule );
tempItem.oShell = _oShell;
tempItem.onPress = function ()
{
if (this.deepLinks.type == "internal")
{
this.oShell.loadWindow( this.deepLinks.wModule , this.deepLinks.wParams);
}
else
{
getURL (this.deepLinks.link, "_blank");
}
this.refToClass.closeWindow ();
}
}
}
} else
{
trace ("end tab " + _refWindow);
}
}
/**
* Enter description here
*
* #param evt
*/
private function onLogoutHandler (evt : Object) : Void
{
_oWindowManagerRef.removeEventListener ("onLogout", _oLogoutDelegate);
closeWindow ();
}
/**
* Enter description here
*
*/
public function closeMyWindow () : Void
{
_global._doNav ('windowType:wclose')
}
/**
* Enter description here
*
*/
public function removeMyWindow () : Void
{
_oWindowManagerRef.removeWindow (idWindow);
}
}
If you can see from this part of the code
if (aNextdata != undefined && aNextdata.length > 0)
I am getting three links one below the other but my problem is only the first link is opening in a new page which is supposed to open in the same page so what should I do for this Please help me thankyou.
Hard to say from your question, but it could be the getUrl-call that is causing your link to open in a new window. The second, optional, parameter to getUrl specifies the window in which the link should open. If you replace
getURL (this.deepLinks.link, "_blank");
with
getURL (this.deepLinks.link);
Your link should open in the same window.

Resources