microsoft / typed-rest-client Goto Github PK
View Code? Open in Web Editor NEWNode Rest and Http Clients with typings for use with TypeScript
License: Other
Node Rest and Http Clients with typings for use with TypeScript
License: Other
Node version: 8.10
Npm version: 5.8.0
OS and version: MacOS 10.13.3
typed-rest-client version: stable
When using a type for the response which has Date as type for a field, that field ends up being a string, thus violating the type.
If I have a field which is a Date, I expect the deserialization to fail whenever the returned type isn't a date, or if the type does represent a parseable Date, that the field gets correctly transformed into a Date.
Instead of a Date, we get string. This means that any code that I write expecting there to be a Date, becomes type-unsafe as all the Date methods are not available in string objects.
As I understand, this may be tricky to solve as JSON.parse
will see a string and leave it as a string. However, we could possibly introspect the type of the response and handle the Date manually.
I think should use const instead of var.
The simplest example failed this error. After debugging I found that lib/Utils.js
has the failing call: path.posix.resolve(base.pathname, resultantUrl.pathname)
; but path.posix
is undefined with my setup. This setup is basically a React web app (meaning that the code is executed on the browser VM rather than by Node), on a Windows 10 box, if that makes a difference. I've simply replaced the call with path.resolve(base.pathname, resultantUrl.pathname)
, and it works, but I'm not sure if this is altering the outcome for some case.
Stack trace:
TypeError: Cannot read property 'resolve' of undefined
at Object.getUrl (http://localhost:3000/static/js/bundle.js:66588:40)
at RestClient.<anonymous> (http://localhost:3000/static/js/bundle.js:66412:28
at Generator.next (<anonymous>) at http://localhost:3000/static/js/bundle.js:66370:71
at new Promise (<anonymous>)
at ./node_modules/typed-rest-client/RestClient.js.__awaiter (http://localhost:3000/static/js/bundle.js:66366:12)
at RestClient.get (http://localhost:3000/static/js/bundle.js:66411:16)
at TodoStore../src/model/TodoStore.ts.TodoStore.loadTodos (http://localhost:3000/static/js/bundle.js:69754:29)
at Object../src/App.tsx (http://localhost:3000/static/js/bundle.js:69321:11)
at __webpack_require__ (http://localhost:3000/static/js/bundle.js:679:30)
at fn (http://localhost:3000/static/js/bundle.js:89:20)
at Object../src/index.tsx (http://localhost:3000/static/js/bundle.js:69614:63)
at __webpack_require__ (http://localhost:3000/static/js/bundle.js:679:30)
at fn (http://localhost:3000/static/js/bundle.js:89:20)
at Object.0 (http://localhost:3000/static/js/bundle.js:70021:18)
at __webpack_require__ (http://localhost:3000/static/js/bundle.js:679:30)
at ./node_modules/ansi-regex/index.js.module.exports (http://localhost:3000/static/js/bundle.js:725:37)
at http://localhost:3000/static/js/bundle.js:728:10
We currently have samples of how to use the code but should also add unit tests.
Could you possibly add rest request samples with custom headers and with Basic and Bearer support?
0 info it worked if it ends with ok
1 verbose cli [ 'C:\Program Files (x86)\nodejs\node.exe',
1 verbose cli 'C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js',
1 verbose cli 'run',
1 verbose cli 'build' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle [email protected]prebuild: [email protected]prebuild: no script for prebuild, continuing
6 silly lifecycle [email protected]
7 info lifecycle [email protected]build: [email protected]build: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]
9 verbose lifecycle [email protected]build: PATH: C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\bin\node-gyp-bin;C:\andrei\typed-rest-client\node_modules.bin;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Broadcom\Broadcom 802.11;C:\Program Files (x86)\Intel\iCLS Client;C:\Program Files\Intel\iCLS Client;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files\Hewlett-Packard\SimplePass;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit;C:\Program Files\Microsoft SQL Server\110\Tools\Binn;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0;C:\Program Files\Microsoft SQL Server\120\Tools\Binn;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit;C:\Users\Massimo.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm;C:\Program Files\Microsoft\Web Platform Installer;C:\Program Files (x86)\Microsoft SDKs\Azure\CLI\wbin;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files (x86)\Windows Phone TShell;C:\Program Files\Microsoft SQL Server\130\Tools\Binn;C:\Program Files (x86)\nodejs;C:\Program Files (x86)\Skype\Phone;C:\Program Files\dotnet;C:\Program Files\Git\cmd;C:\Users\Massimo.dnx\bin;C:\Users\Massimo\AppData\Local\Code\bin;C:\Program Files (x86)\Microsoft VS Code\bin;c:\Users\Massimo\AppData\Local\Android\sdk\platform-tools;C:\Users\Massimo\Downloads\watchman;C:\Users\Massimo\AppData\Local\Microsoft\WindowsApps;C:\Users\Massimo\AppData\Roaming\npm;C:\maven\bin;C:\OpenSSL-Win64\bin;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;build: CWD: C:\andrei\typed-rest-client
10 verbose lifecycle [email protected]
11 silly lifecycle [email protected]build: Args: [ '/d /s /c', 'node make.js build' ]build: Returned: code: 1 signal: null
12 silly lifecycle [email protected]
13 info lifecycle [email protected]~build: Failed to exec build script
14 verbose stack Error: [email protected] build: node make.js build
14 verbose stack Exit status 1
14 verbose stack at EventEmitter. (C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\lib\utils\lifecycle.js:279:16)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:191:7)
14 verbose stack at ChildProcess. (C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\lib\utils\spawn.js:40:14)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:191:7)
14 verbose stack at maybeClose (internal/child_process.js:886:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
15 verbose pkgid [email protected]
16 verbose cwd C:\andrei\typed-rest-client
17 verbose Windows_NT 10.0.15063
18 verbose argv "C:\Program Files (x86)\nodejs\node.exe" "C:\Users\Massimo\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js" "run" "build"
19 verbose node v6.10.2
20 verbose npm v4.5.0
21 error code ELIFECYCLE
22 error errno 1
23 error [email protected] build: node make.js build
23 error Exit status 1
24 error Failed at the [email protected] build script 'node make.js build'.
24 error Make sure you have the latest version of node.js and npm installed.
24 error If you do, this is most likely a problem with the typed-rest-client package,
24 error not with npm itself.
24 error Tell the author that this fails on your system:
24 error node make.js build
24 error You can get information on how to open an issue for this project with:
24 error npm bugs typed-rest-client
24 error Or if that isn't available, you can get their info via:
24 error npm owner ls typed-rest-client
24 error There is likely additional logging output above.
25 verbose exit [ 1, true ]
Here is my GIT SHA:
C:\andrei\typed-rest-client>git log
commit f486197
Author: Bryan MacFarlane [email protected]
Date: Tue Mar 28 16:30:56 2017 -0400
added options request
Sorry if this is the wrong place to add this but when I am trying to use the library in a project I am getting an error saying that the http.globalAgent is undefined.
At that point http.Agent is available but for some reason not the globalAgent.
Commenting this out or setting the maxSockets in the Agent seems to work properly
http.Agent.maxSockets = 100;
Sorry but I was not able to get more info out of the documentation and ensured that I have the latest node and everything.
Even though npm run build and npm run test seems to work without any issues.
Here is a small sample of how I tried to use the library
import * as rm from 'typed-rest-client/RestClient';
interface Student {
message: string
};
async function runSample() {
let restc: rm.RestClient = new rm.RestClient('rest-samples', 'https://sample-api.dev');
let res: rm.IRestResponse<Student> = await restc.get<Student>('/ping');
console.log(res.statusCode);
console.log(res.result);
console.log('aha');
}
runSample();
The final file is complied with webpack
and I just include the final .js file into the html sample page where I get the error about the http.globalAgent.
Is there a specific reason why you setup the maxSocket at that point and not further down the code like you do for the httpProxy?
Hope the above makes sense.
For any clarifications plz let me know
If this does not make sense or you believe it is irrelevant then plz close it
Thank you
Hello.
While following on contributing guide, I had an error in npm run samples
.
> [email protected] samples /Users/kwangin/workspace/github_source/typed-rest-client
> node make.js samples
> /Users/kwangin/workspace/github_source/typed-rest-client/node_modules/.bin/tsc --outDir /Users/kwangin/workspace/github_source/typed-rest-client/_build
/Users/kwangin/workspace/github_source/typed-rest-client/samples /Users/kwangin/workspace/github_source/typed-rest-client
> node samples.js
module.js:491
throw err;
^
Error: Cannot find module '/Users/kwangin/workspace/github_source/typed-rest-client/samples/samples.js'
at Function.Module._resolveFilename (module.js:489:15)
at Function.Module._load (module.js:439:25)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:578:3
/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/common.js:381
if (config.fatal) throw e;
^
Error: exec: internal error
at Object.error (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/common.js:112:27)
at _exec (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/exec.js:292:12)
at /Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/src/common.js:316:23
at run (/Users/kwangin/workspace/github_source/typed-rest-client/make.js:14:14)
at Function.target.samples (/Users/kwangin/workspace/github_source/typed-rest-client/make.js:51:5)
at Object.global.target.(anonymous function) [as samples] (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/make.js:36:40)
at /Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/make.js:48:27
at Array.forEach (<anonymous>)
at Timeout._onTimeout (/Users/kwangin/workspace/github_source/typed-rest-client/node_modules/shelljs/make.js:46:10)
at ontimeout (timers.js:469:11)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] samples: `node make.js samples`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] samples script.
Am I doing something wrong?
My node version is v8.3.0
, and npm is 5.5.1
.
Thanks.
As part of the HttpClient, we were looking for a feature which enables us to retry the Http calls in case of specific errors (ex: 502 Bad Gateway or 504 Gateway Timeout).
One yaml file
3 defs (linux, osx and windows). Use hosted linux, OSX and VS2017 pools
Hello I'm using you client but I'm having some issues to set the auth cookie in the request
this.client = new rm.HttpClient('prevent-client');
var headers = {
"Content-Type": "application/json",
"Set-Cookie": this.cookieJar
};
var payload = {'cpid': 200};
var responseStream = await this.client.post(this.host, JSON.stringify(payload), headers);
But the cookies are not sent to the server. Any ideas how to solve this? Thanks.
Once again, thanks for your had work on this library :)
Could you please, prior to publication of this library on NPM, include in your build script (if any) a tagging of the current version in GIT ?
When using a specify published version of your lib, it would be useful to have a tag on the version tree in order to
There are severall methods, here is one, for example
https://coderwall.com/p/mk18zq/automatic-git-version-tagging-for-npm-modules
Thanks :)
Node version: 8.12
Npm version: 6.4.1
OS and version: windows 10
typed-rest-client version: 1.0.11
I want to receive a file from server. server reponse binary file in body, but http client in this module override all non ascii byte to 65533. I figure out that reponse data is converted to string. Any method to deal with binary data?
Hi again,
this is mainly a question/request.
We currently use the library for browser usage and as we would like to be able and support IE11 the current npm package is not compatible as the compilation is targeted for es2015.
(The issue is that after compilation the files keep the class references which are not supported by IE11).
We have tried to work a solution with that and we have forked and updated the required files to target es5.
Our script works awesome with this change.
You can view the fork and branch here
https://github.com/baxevanis/typed-rest-client/tree/feature/support_es5
Please be aware that we also install the package through npm and github and that is why we had to add some additional configuration in the package.json (prepare and postinstall) to ensure npm can properly install the package.
So I have two questions:
If we are to make a pull request with the target change to es5, would you consider accepting this change or your script relies on using es2015 explicitly?
Can we publish a new npm package ex: typed-rest-client-es5 that will support es5? (by doing this we can clean up the additional changes that are required to install the package from github).
Thank you
Nikolaos
Would you be so kind to provide us an example on how to efficiently download a large file with the http client?
It may sound trivial as a question, however for someone starting with Node and TS, aiming to build an efficient build task, this could be very useful.
Thanks
Shouldn't RestClient declare a post method? :)
At the following line, in case of, let's say a 400 response that returns a body that is not JSON content
the code will fail. This means that no matter which responseProcessor function we specify, it will never be reached.
A better approach would be to just wrap that line in something like this:
try {
obj = JSON.parse(contents);
} catch (e) {
}
This will allow us to specify a custom responseProcessor function which then will bring the simple error string in the exception.
If you agree, I'll submit a PR.
LTS Node >= 6.12.0 and Npm 5.5.1
Automate building and testing against all supported node versions using nvm.
Potentially call it testallversions.
Node version: 8.10
Npm version: 5.8.0
OS and version: MacOS 10.13.3
typed-rest-client version: stable
Using Typed Rest Client without specifying a base URL does not play well with non-default ports. I was using a node server on port 3000 and without specifying a URL, it tries to send requests as follows:
http://localhost:3000/:80/product/abca
I expect it to behave like the fetch
polyfill, where as if a base URL is not specified, it takes the request URL as an absolute URL for the current host:port combination. In my specific case, when I do a request to /product/abca
, I expect the request to go to http://localhost:3000/product/abca
.
Currently it seems to be a weird hybrid as since I didn't specify a base URL and my requests are relative, it appends the port and probably has an empty hostname. Basically currently we have a strange behavior, which possibly should throw an error if we don't want to support empty base URL + relative requests.
Not relevant.
Should test all of them, but especially NTLM since it doesn't do preauth and is pretty fragile
Hey there, so I noticed that this project and my project RESTyped (https://github.com/rawrmaan/restyped) launched at similar times. I'm trying to understand the exact goals of this project and if it might be worthwhile to combine our efforts here.
Any thoughts? Thanks!
I think it would be better to add a mocking library which nock is to the devDependencies, because this should not be deployed on production systems. Other opinions about this?
Investigate replacing httpbin requests with Nock.
Would give us more control. Easier to test authentication too?
In the rest client there is a check if additional headers are specified.
In case user specifies a custom Content-Type header (necessary at example in case we are using uploadStream to upload a file via mutipart/formdata standard (RFC 2388) the default one will not be added.
The problem is that the check over Content-Type header is case sensitive, so if you added a content-type header, this will not be detected and used correctly.
I would suggest to use a non case sensitive check for this.
If you guys do agree with me, I have a code ready and I'll request a PR.
Thanks
Node version: 10.0.0
Npm version: 5.6.0
OS and version: Windows 10
typed-rest-client version: 1.0.7
Created a new Angular 6 project, added typed-rest-client.
Created a component which uses NtlmCredentialHandler and HttpClient and compiled. I get the errors below.
No errors should occur on build.
The following errors occur on build:
ERROR in ./node_modules/typed-rest-client/opensource/node-http-ntlm/ntlm.js
Module not found: Error: Can't resolve 'crypto' in 'C:\myapp\node_modules\typed-rest-client\opensource\node-http-ntlm'
ERROR in ./node_modules/typed-rest-client/handlers/ntlm.js
Module not found: Error: Can't resolve 'http' in 'C:\myapp\node_modules\typed-rest-client\handlers'
ERROR in ./node_modules/typed-rest-client/handlers/ntlm.js
Module not found: Error: Can't resolve 'https' in 'C:\myapp\node_modules\typed-rest-client\handlers'
@bryanmacfarlane Does HttpClient support multipart uploads? If so please provide an example.
In the distributed npm package, Index.d.ts
has /// <reference path="../typings/index.d.ts" />
which prevents it from compiling. It works fine after I delete the file. Can we remove this?
Also, the documentation encourages installation of typings
which was deprecated long time back. Can we update it to follow the best practices?
Currently the request using global node agent for request in some cases and in other cases agent option isn't passed while making the rest api call.
We make a lot of calls to the same host in our tasks, currently these call are leading to create of new sockets, we want to be able to reuse sockets by setting keepAlive. We also want to throttle these calls by limiting maxSockets on the agent. Also, using an custom agent will not affect the calls made using global node agent.
We should expose handlers at https://github.com/Microsoft/typed-rest-client/tree/master/lib so that they can be used by consumers. Instead clients currently need to copy them like in vso-node-api https://github.com/Microsoft/vsts-node-api/tree/master/api/handlers and item-level-downloader https://github.com/Microsoft/vsts-rm-extensions/tree/master/ItemLevelDownloader/Providers/Handlers
I cannot use this library on linux, because of inconsistent casing of files. Take bearertoken.d.ts as an example, it is importing '../interfaces
. A file interfaces.d.ts
does not exist, it should have been including '../Interfaces'
.
Results in this error:
src/client/HttpClient.ts(5,33): error TS2307: Cannot find module 'typed-rest-client/interfaces'.
Node version: 8.9.4
Npm version: 5.6.0
OS and version: MacOS High Sierra
typed-rest-client version: 1.0.9
I can't configure the proxy. Not sure if there is a bug or if I messed up sth.
Also, my script is run by protractor with a configured proxy
Add example how to use a proxy (and verify it)
I got the following error:
tunneling socket could not be established, cause=connect ETIMEDOUT ip address:port
The diff below shows how to use httpntlm
module as direct, explicit dependency in the project without worrying of correctly meeting MIT license requirements. The change seems to be opaque to implementation (including current tests). Do you think that this could make a project structure cleaner and easier to maintain?
commit 167bdf1a32366f1abc6c7a23d33b18ba1176c0a9
Author: Peter Blazejewicz <[email protected]>
Date: Mon Nov 20 21:54:12 2017 +0100
Use NPM distributed version of httpntlm package
diff --git a/lib/handlers/ntlm.ts b/lib/handlers/ntlm.ts
index 483aff6..bcdd8b2 100644
--- a/lib/handlers/ntlm.ts
+++ b/lib/handlers/ntlm.ts
@@ -5,8 +5,8 @@ import VsoBaseInterfaces = require('../interfaces');
import http = require("http");
import https = require("https");
-var _ = require("underscore");
-var ntlm = require("../opensource/node-http-ntlm/ntlm");
+const _ = require("underscore");
+const ntlm = require("httpntlm");
export class NtlmCredentialHandler implements VsoBaseInterfaces.IRequestHandler {
username: string;
diff --git a/lib/opensource/node-http-ntlm/ntlm.js b/lib/opensource/node-http-ntlm/ntlm.js
deleted file mode 100644
index 5a776c3..0000000
--- a/lib/opensource/node-http-ntlm/ntlm.js
+++ /dev/null
@@ -1,390 +0,0 @@
-var crypto = require('crypto');
-
-var flags = {
- NTLM_NegotiateUnicode : 0x00000001,
- NTLM_NegotiateOEM : 0x00000002,
- NTLM_RequestTarget : 0x00000004,
- NTLM_Unknown9 : 0x00000008,
- NTLM_NegotiateSign : 0x00000010,
- NTLM_NegotiateSeal : 0x00000020,
- NTLM_NegotiateDatagram : 0x00000040,
- NTLM_NegotiateLanManagerKey : 0x00000080,
- NTLM_Unknown8 : 0x00000100,
- NTLM_NegotiateNTLM : 0x00000200,
- NTLM_NegotiateNTOnly : 0x00000400,
- NTLM_Anonymous : 0x00000800,
- NTLM_NegotiateOemDomainSupplied : 0x00001000,
- NTLM_NegotiateOemWorkstationSupplied : 0x00002000,
- NTLM_Unknown6 : 0x00004000,
- NTLM_NegotiateAlwaysSign : 0x00008000,
- NTLM_TargetTypeDomain : 0x00010000,
- NTLM_TargetTypeServer : 0x00020000,
- NTLM_TargetTypeShare : 0x00040000,
- NTLM_NegotiateExtendedSecurity : 0x00080000,
- NTLM_NegotiateIdentify : 0x00100000,
- NTLM_Unknown5 : 0x00200000,
- NTLM_RequestNonNTSessionKey : 0x00400000,
- NTLM_NegotiateTargetInfo : 0x00800000,
- NTLM_Unknown4 : 0x01000000,
- NTLM_NegotiateVersion : 0x02000000,
- NTLM_Unknown3 : 0x04000000,
- NTLM_Unknown2 : 0x08000000,
- NTLM_Unknown1 : 0x10000000,
- NTLM_Negotiate128 : 0x20000000,
- NTLM_NegotiateKeyExchange : 0x40000000,
- NTLM_Negotiate56 : 0x80000000
-};
-var typeflags = {
- NTLM_TYPE1_FLAGS : flags.NTLM_NegotiateUnicode
- + flags.NTLM_NegotiateOEM
- + flags.NTLM_RequestTarget
- + flags.NTLM_NegotiateNTLM
- + flags.NTLM_NegotiateOemDomainSupplied
- + flags.NTLM_NegotiateOemWorkstationSupplied
- + flags.NTLM_NegotiateAlwaysSign
- + flags.NTLM_NegotiateExtendedSecurity
- + flags.NTLM_NegotiateVersion
- + flags.NTLM_Negotiate128
- + flags.NTLM_Negotiate56,
-
- NTLM_TYPE2_FLAGS : flags.NTLM_NegotiateUnicode
- + flags.NTLM_RequestTarget
- + flags.NTLM_NegotiateNTLM
- + flags.NTLM_NegotiateAlwaysSign
- + flags.NTLM_NegotiateExtendedSecurity
- + flags.NTLM_NegotiateTargetInfo
- + flags.NTLM_NegotiateVersion
- + flags.NTLM_Negotiate128
- + flags.NTLM_Negotiate56
-};
-
-function createType1Message(options){
- var domain = escape(options.domain.toUpperCase());
- var workstation = escape(options.workstation.toUpperCase());
- var protocol = 'NTLMSSP\0';
-
- var BODY_LENGTH = 40;
-
- var type1flags = typeflags.NTLM_TYPE1_FLAGS;
- if(!domain || domain === '')
- type1flags = type1flags - flags.NTLM_NegotiateOemDomainSupplied;
-
- var pos = 0;
- var buf = new Buffer(BODY_LENGTH + domain.length + workstation.length);
-
-
- buf.write(protocol, pos, protocol.length); pos += protocol.length; // protocol
- buf.writeUInt32LE(1, pos); pos += 4; // type 1
- buf.writeUInt32LE(type1flags, pos); pos += 4; // TYPE1 flag
-
- buf.writeUInt16LE(domain.length, pos); pos += 2; // domain length
- buf.writeUInt16LE(domain.length, pos); pos += 2; // domain max length
- buf.writeUInt32LE(BODY_LENGTH + workstation.length, pos); pos += 4; // domain buffer offset
-
- buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation length
- buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation max length
- buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // workstation buffer offset
-
- buf.writeUInt8(5, pos); pos += 1; //ProductMajorVersion
- buf.writeUInt8(1, pos); pos += 1; //ProductMinorVersion
- buf.writeUInt16LE(2600, pos); pos += 2; //ProductBuild
-
- buf.writeUInt8(0 , pos); pos += 1; //VersionReserved1
- buf.writeUInt8(0 , pos); pos += 1; //VersionReserved2
- buf.writeUInt8(0 , pos); pos += 1; //VersionReserved3
- buf.writeUInt8(15, pos); pos += 1; //NTLMRevisionCurrent
-
- buf.write(workstation, pos, workstation.length, 'ascii'); pos += workstation.length; // workstation string
- buf.write(domain , pos, domain.length , 'ascii'); pos += domain.length;
-
- return 'NTLM ' + buf.toString('base64');
-}
-
-function parseType2Message(rawmsg, callback){
- var match = rawmsg.match(/NTLM (.+)?/);
- if(!match || !match[1])
- return callback(new Error("Couldn't find NTLM in the message type2 comming from the server"));
-
- var buf = new Buffer(match[1], 'base64');
-
- var msg = {};
-
- msg.signature = buf.slice(0, 8);
- msg.type = buf.readInt16LE(8);
-
- if(msg.type != 2)
- return callback(new Error("Server didn't return a type 2 message"));
-
- msg.targetNameLen = buf.readInt16LE(12);
- msg.targetNameMaxLen = buf.readInt16LE(14);
- msg.targetNameOffset = buf.readInt32LE(16);
- msg.targetName = buf.slice(msg.targetNameOffset, msg.targetNameOffset + msg.targetNameMaxLen);
-
- msg.negotiateFlags = buf.readInt32LE(20);
- msg.serverChallenge = buf.slice(24, 32);
- msg.reserved = buf.slice(32, 40);
-
- if(msg.negotiateFlags & flags.NTLM_NegotiateTargetInfo){
- msg.targetInfoLen = buf.readInt16LE(40);
- msg.targetInfoMaxLen = buf.readInt16LE(42);
- msg.targetInfoOffset = buf.readInt32LE(44);
- msg.targetInfo = buf.slice(msg.targetInfoOffset, msg.targetInfoOffset + msg.targetInfoLen);
- }
- return msg;
-}
-
-function createType3Message(msg2, options){
- var nonce = msg2.serverChallenge;
- var username = options.username;
- var password = options.password;
- var negotiateFlags = msg2.negotiateFlags;
-
- var isUnicode = negotiateFlags & flags.NTLM_NegotiateUnicode;
- var isNegotiateExtendedSecurity = negotiateFlags & flags.NTLM_NegotiateExtendedSecurity;
-
- var BODY_LENGTH = 72;
-
- var domainName = escape(options.domain.toUpperCase());
- var workstation = escape(options.workstation.toUpperCase());
-
- var workstationBytes, domainNameBytes, usernameBytes, encryptedRandomSessionKeyBytes;
-
- var encryptedRandomSessionKey = "";
- if(isUnicode){
- workstationBytes = new Buffer(workstation, 'utf16le');
- domainNameBytes = new Buffer(domainName, 'utf16le');
- usernameBytes = new Buffer(username, 'utf16le');
- encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'utf16le');
- }else{
- workstationBytes = new Buffer(workstation, 'ascii');
- domainNameBytes = new Buffer(domainName, 'ascii');
- usernameBytes = new Buffer(username, 'ascii');
- encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'ascii');
- }
-
- var lmChallengeResponse = calc_resp(create_LM_hashed_password_v1(password), nonce);
- var ntChallengeResponse = calc_resp(create_NT_hashed_password_v1(password), nonce);
-
- if(isNegotiateExtendedSecurity){
- var pwhash = create_NT_hashed_password_v1(password);
- var clientChallenge = "";
- for(var i=0; i < 8; i++){
- clientChallenge += String.fromCharCode( Math.floor(Math.random()*256) );
- }
- var clientChallengeBytes = new Buffer(clientChallenge, 'ascii');
- var challenges = ntlm2sr_calc_resp(pwhash, nonce, clientChallengeBytes);
- lmChallengeResponse = challenges.lmChallengeResponse;
- ntChallengeResponse = challenges.ntChallengeResponse;
- }
-
- var signature = 'NTLMSSP\0';
-
- var pos = 0;
- var buf = new Buffer(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length + encryptedRandomSessionKeyBytes.length);
-
- buf.write(signature, pos, signature.length); pos += signature.length;
- buf.writeUInt32LE(3, pos); pos += 4; // type 1
-
- buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseLen
- buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseMaxLen
- buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length, pos); pos += 4; // LmChallengeResponseOffset
-
- buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseLen
- buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseMaxLen
- buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length, pos); pos += 4; // NtChallengeResponseOffset
-
- buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameLen
- buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameMaxLen
- buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // DomainNameOffset
-
- buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameLen
- buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameMaxLen
- buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length, pos); pos += 4; // UserNameOffset
-
- buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationLen
- buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationMaxLen
- buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length, pos); pos += 4; // WorkstationOffset
-
- buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyLen
- buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyMaxLen
- buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length, pos); pos += 4; // EncryptedRandomSessionKeyOffset
-
- buf.writeUInt32LE(typeflags.NTLM_TYPE2_FLAGS, pos); pos += 4; // NegotiateFlags
-
- buf.writeUInt8(5, pos); pos++; // ProductMajorVersion
- buf.writeUInt8(1, pos); pos++; // ProductMinorVersion
- buf.writeUInt16LE(2600, pos); pos += 2; // ProductBuild
- buf.writeUInt8(0, pos); pos++; // VersionReserved1
- buf.writeUInt8(0, pos); pos++; // VersionReserved2
- buf.writeUInt8(0, pos); pos++; // VersionReserved3
- buf.writeUInt8(15, pos); pos++; // NTLMRevisionCurrent
-
- domainNameBytes.copy(buf, pos); pos += domainNameBytes.length;
- usernameBytes.copy(buf, pos); pos += usernameBytes.length;
- workstationBytes.copy(buf, pos); pos += workstationBytes.length;
- lmChallengeResponse.copy(buf, pos); pos += lmChallengeResponse.length;
- ntChallengeResponse.copy(buf, pos); pos += ntChallengeResponse.length;
- encryptedRandomSessionKeyBytes.copy(buf, pos); pos += encryptedRandomSessionKeyBytes.length;
-
- return 'NTLM ' + buf.toString('base64');
-}
-
-function create_LM_hashed_password_v1(password){
- // fix the password length to 14 bytes
- password = password.toUpperCase();
- var passwordBytes = new Buffer(password, 'ascii');
-
- var passwordBytesPadded = new Buffer(14);
- passwordBytesPadded.fill("\0");
- var sourceEnd = 14;
- if(passwordBytes.length < 14) sourceEnd = passwordBytes.length;
- passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd);
-
- // split into 2 parts of 7 bytes:
- var firstPart = passwordBytesPadded.slice(0,7);
- var secondPart = passwordBytesPadded.slice(7);
-
- function encrypt(buf){
- var key = insertZerosEvery7Bits(buf);
- var des = crypto.createCipheriv('DES-ECB', key, '');
- return des.update("KGS!@#$%"); // page 57 in [MS-NLMP]);
- }
-
- var firstPartEncrypted = encrypt(firstPart);
- var secondPartEncrypted = encrypt(secondPart);
-
- return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
-}
-
-function insertZerosEvery7Bits(buf){
- var binaryArray = bytes2binaryArray(buf);
- var newBinaryArray = [];
- for(var i=0; i<binaryArray.length; i++){
- newBinaryArray.push(binaryArray[i]);
-
- if((i+1)%7 === 0){
- newBinaryArray.push(0);
- }
- }
- return binaryArray2bytes(newBinaryArray);
-}
-
-function bytes2binaryArray(buf){
- var hex2binary = {
- 0: [0,0,0,0],
- 1: [0,0,0,1],
- 2: [0,0,1,0],
- 3: [0,0,1,1],
- 4: [0,1,0,0],
- 5: [0,1,0,1],
- 6: [0,1,1,0],
- 7: [0,1,1,1],
- 8: [1,0,0,0],
- 9: [1,0,0,1],
- A: [1,0,1,0],
- B: [1,0,1,1],
- C: [1,1,0,0],
- D: [1,1,0,1],
- E: [1,1,1,0],
- F: [1,1,1,1]
- };
-
- var hexString = buf.toString('hex').toUpperCase();
- var array = [];
- for(var i=0; i<hexString.length; i++){
- var hexchar = hexString.charAt(i);
- array = array.concat(hex2binary[hexchar]);
- }
- return array;
-}
-
-function binaryArray2bytes(array){
- var binary2hex = {
- '0000': 0,
- '0001': 1,
- '0010': 2,
- '0011': 3,
- '0100': 4,
- '0101': 5,
- '0110': 6,
- '0111': 7,
- '1000': 8,
- '1001': 9,
- '1010': 'A',
- '1011': 'B',
- '1100': 'C',
- '1101': 'D',
- '1110': 'E',
- '1111': 'F'
- };
-
- var bufArray = [];
-
- for(var i=0; i<array.length; i +=8 ){
- if((i+7) > array.length)
- break;
-
- var binString1 = '' + array[i] + '' + array[i+1] + '' + array[i+2] + '' + array[i+3];
- var binString2 = '' + array[i+4] + '' + array[i+5] + '' + array[i+6] + '' + array[i+7];
- var hexchar1 = binary2hex[binString1];
- var hexchar2 = binary2hex[binString2];
-
- var buf = new Buffer(hexchar1 + '' + hexchar2, 'hex');
- bufArray.push(buf);
- }
-
- return Buffer.concat(bufArray);
-}
-
-function create_NT_hashed_password_v1(password){
- var buf = new Buffer(password, 'utf16le');
- var md4 = crypto.createHash('md4');
- md4.update(buf);
- return new Buffer(md4.digest());
-}
-
-function calc_resp(password_hash, server_challenge){
- // padding with zeros to make the hash 21 bytes long
- var passHashPadded = new Buffer(21);
- passHashPadded.fill("\0");
- password_hash.copy(passHashPadded, 0, 0, password_hash.length);
-
- var resArray = [];
-
- var des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(0,7)), '');
- resArray.push( des.update(server_challenge.slice(0,8)) );
-
- des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(7,14)), '');
- resArray.push( des.update(server_challenge.slice(0,8)) );
-
- des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(14,21)), '');
- resArray.push( des.update(server_challenge.slice(0,8)) );
-
- return Buffer.concat(resArray);
-}
-
-function ntlm2sr_calc_resp(responseKeyNT, serverChallenge, clientChallenge){
- // padding with zeros to make the hash 16 bytes longer
- var lmChallengeResponse = new Buffer(clientChallenge.length + 16);
- lmChallengeResponse.fill("\0");
- clientChallenge.copy(lmChallengeResponse, 0, 0, clientChallenge.length);
-
- var buf = Buffer.concat([serverChallenge, clientChallenge]);
- var md5 = crypto.createHash('md5');
- md5.update(buf);
- var sess = md5.digest();
- var ntChallengeResponse = calc_resp(responseKeyNT, sess.slice(0,8));
-
- return {
- lmChallengeResponse: lmChallengeResponse,
- ntChallengeResponse: ntChallengeResponse
- };
-}
-
-exports.createType1Message = createType1Message;
-exports.parseType2Message = parseType2Message;
-exports.createType3Message = createType3Message;
-
-
-
-
diff --git a/lib/opensource/node-http-ntlm/readme.txt b/lib/opensource/node-http-ntlm/readme.txt
deleted file mode 100644
index b341600..0000000
--- a/lib/opensource/node-http-ntlm/readme.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-// This software (ntlm.js) was copied from a file of the same name at https://github.com/SamDecrock/node-http-ntlm/blob/master/ntlm.js.
-//
-// As of this writing, it is a part of the node-http-ntlm module produced by SamDecrock.
-//
-// It is used as a part of the NTLM support provided by the vso-node-api library.
-//
diff --git a/make.js b/make.js
index db067fe..dee7eeb 100644
--- a/make.js
+++ b/make.js
@@ -28,7 +28,6 @@ target.build = function () {
run(path.join(__dirname, 'node_modules/.bin/tsc') + ' --outDir ' + buildPath);
// cp(rp('dependencies/typings.json'), buildPath);
- cp('-Rf', rp('lib/opensource'), buildPath);
cp(rp('package.json'), buildPath);
cp(rp('README.md'), buildPath);
cp(rp('LICENSE'), buildPath);
diff --git a/package.json b/package.json
index d42420c..6fe0095 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"@types/mocha": "^2.2.41"
},
"dependencies": {
+ "httpntlm": "1.7.5",
"tunnel": "0.0.4",
"underscore": "1.8.3"
}
Thanks!
The HTTP client does, we need the REST one to also. It will be consumed in the node api.
Right now if ntlmHandler's workstation and domain aren't specified, calls to ntlm.createType1Message (and maybe other methods) fail. They work if workstation and domain are specified, even if they're set to empty strings.
Discovered this while investigating microsoft/azure-devops-node-api#172
FYI - this is where it fails because it tries to call toUppercase on an undefined object
Now to change eg. proxy you have to set global variable, something like this:
process.env.HTTP_PROXY = 'http://127.0.0.1:8080'
Node version: 6.x
Npm version:
OS and version:
typed-rest-client version: 0.15.1
If password has characters like ':' '' proxy doesn't work, since we are url encoding the password at
https://github.com/Microsoft/typed-rest-client/blob/93448b8ffdf5183cddb710d0fde99d7e697026f1/lib/HttpClient.ts#L408
Proxy should work when password has url sensitive characters.
Error: tunneling socket could not be established, statusCode=407
Look at:
typed-rest-client version: 1.0.7
I can instantiate the HttpClient with default headers as follows:
this.httpClient = new HttpClient("myUserAgent", [basicHandler], {headers: {"Accept": "application/json"}});
But it doesn't send these headers to the endpoint. In fact, it doesn't seem to use them at all.
When I send the Accept header as additionalHeader on the get method, everything works as expected
response = await this.httpClient.get("https://example.com/clients", { "Accept": "application/json"});
The default headers, defined in the constructor, should be merged with the additional headers sent along with the get/post/... method.
No default headers are sent to the endpoint.
CI failed on the last commit (before my stream of ugly commits trying to diagnose). Looks like it fails on previous commits as well, so I think this is actually an issue with the CI, not the commit.
Node version:
Npm version: 8.11.4
OS and version: Windows 10
typed-rest-client version: 1.0.9
Currently, in RestClient, calls to the public functions all receive a httpm.HttpClientResponse object which contains headers but return a promise of an IRestResponse object which does not contain headers.
IRestResponse should contain headers
IRestResponse only contains information pulled from the result and the status code.
let restc: RestClient = new RestClient('rest-samples', 'httpbin.org/');
let restRes: IRestResponse<Object> = await restc.get<Object>('get');
Try to get headers from restRes
I've installed typed-rest-client via yarn and npm.
The typings for the 1.0.7 release are empty. which causes intellij to freak out.
Did the last deploy not go well?
hi -- I'm using the create method to post an object to an external REST api. The response returned can have various status codes (even 300+) that indicate various things -- most of which are not actually errors. However, anything that returns with code not 2xx gets handled in the promise's catch block where the promise is rejected -- and the object I get back has properties "message" and "stack", but no status code (or anything else). Since I do need the status code, not just the message -- how do I get it? Thanks in advance.
UPDATE: Looking at the code it seems that you're swallowing this: https://github.com/Microsoft/typed-rest-client/blob/3587b31fe5b77f2d57b3ac5fb0f722fb1485ea6e/lib/RestClient.ts#L210-L220
Is there really no way to get the exact status code of a non-2xx response??? I find that hard to fathom.
In addition, what if one needs other info from a non-2xx response, like its data?
Just had a bug that turned out to be caused by the base "url" effectively being a "base domain."
For example, if you set the base url to http://example.com/common/base/path
and then call a method with a relative path of /relative/path
the client will end up calling http://example.com/relative/path
.
From my experience, it's pretty common for REST API's to have a common base url that includes path elements and it is also common for client implementations to accept common path elements in the base url.
I think it would be a lot more user-friendly and conventional to support path elements in the base url.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.