okta / okta-sdk-nodejs Goto Github PK
View Code? Open in Web Editor NEWNode.js API Client for the Okta Platform API
License: Other
Node.js API Client for the Okta Platform API
License: Other
I'm writing a simple script which attempts to enumerate through every user in my org. I have roughly 5k users.
When I run the following script:
const client = new okta.Client({
orgUrl: "https://dev-842917.oktapreview.com",
token: "xxx",
requestExecutor: new okta.DefaultRequestExecutor()
});
let total = 0;
client.listUsers().each(user => {
console.log(user);
total++;
}).then(() => {
console.log("Listed " + total + " users.");
process.exit();
});
It only iterates through 199 users then stops. Looks like it fetches maybe one or two pages of results and gives up? Any idea why?
I am using the https://github.com/okta/okta-sdk-nodejs from a meteor node app not fully compatible with ES6 features yet.
Do you have a transpiled version of the library to use with older apps ?
Or are you open to a PR that allows this ? master...vurankar:master
or I am open to any other options that will get me rolling.
I do not want to maintain a fork just for this reason.
Hi Team,
We're using endpoint {{url}}/api/v1/users/{{userId}} with body:
{
"credentials": {
"password" : { "value": "newPssword" }
}
}
to reset password from our backend services.
If We send the same password more than 5 times, it does not apply organization policy "Your password cannot be any of your last 5 passwords."
Other policies work as we expected e.g password like "abc" or short password (Peru) return correct okta error (See atachment)
When retrieving a profile that contains very large values, the getUser
function fails to return. To recreate this, create a custom string attribute (avatar
for example). Then set the value to something large - in my case I used a 600kb image converted to a data URI (there are online tools to make this easy, such as https://dopiaza.org/tools/datauri/index.php).
If this is done with user.update()
then the next call to getUser
for that user will return the right value. However, if the user is not already in cache and needs to be fetched from the API, then getUser
will never return.
It's not clear to me yet if this is a problem with the API not returning, or if it's a problem with this node module. When looking at the user's profile in the Okta admin panel, the string is viewable and can be edited. After clearing the value, the getUser
function will work again for that user.
Hi,
flat 2.0.1 is used as a dependency in package.json.
Currently our scan in fortify show us flat as a dependency with vulnerability https://www.npmjs.com/package/flat/v/2.0.1
is there any plan to upgrade version of that dependency.?
Your docs state that:
If you're using a version of Node 10 or greater, you can use async iterators.
for await (let user of client.listUsers()) { console.log(user); }For more information about this API see Users: Get User.
(source: https://github.com/okta/okta-sdk-nodejs#list-all-org-users)
This does not work if there's only one element in the collection.
Fixed by #191
Referring to code introduced in this PR
https://github.com/okta/okta-sdk-nodejs/pull/128/files
https://developer.okta.com/docs/guides/implement-oauth-for-okta/overview/
The access tokens used for OAuth for Okta feature only last an hour. When using the private_key_jwt authentication access tokens instead of the traditional API Token, this SDK does not renew them so API requests from this SDK will just start failing after an hour. Here is a code snippet to reproduce
https://pastebin.com/N0eLisqU
There should be some additional logic to renew tokens ideally before they even expire.
test2
With this basic usage of our collection instances, the process will not exit after the collection each() promise is fulfilled:
const okta = require('@okta/okta-sdk-nodejs');
const client = new okta.Client({
orgUrl: 'https://{yourOktaDomain}.com/',
token: '{your_api_token}',
})
client.listUsers()
.each(user => {
console.log(user);
})
.then(() => {
// this line gets hit, but the process does not terminate
console.log('All users have been visited');
})
.catch((err) => {
console.log(err);
})
Hello,
Is there a way to check that a group exist using "filter" instead of "q" with listGroups() based on the "profile name " ?
I tried profile.name
but it returns an error.
Thanks.
I'm seeking the version 3 changelogs, there are any documentations?
Thanks
test
Hi,
I have a question for you guys! Looking at the nitty-gritty of your code I've found this:
okta-sdk-nodejs/src/resource.js
Lines 22 to 26 in 0bb6f63
And I don't get the "why" of the Object.defineProperty() usage, since the MDN docs > Object > defineProperty say that descriptor's "enumerable" key is false
by default.
Thanks in advance!
We should add an example to the readme that demonstrates how to use this client to make arbitrary calls to the Okta API (i.e. endpoints that are not yet officially supported by the library).
For reference, see the SDK readme template here: https://gist.github.com/nbarbettini/c0f44cf08b6d99b39cd59e533842a684#call-other-api-endpoints
It would be great if we could mark a lot of the core SDK methods as async
functions so you can use async/await patterns more easily.
A common use case, for example, is iterating through org users and doing something with each user. For instance:
client.listUsers().each(user => {
// code here
await someAsyncFunctionIWrote(); // <--- this always fails since .each() isn't async :(
});
If we make the iterators proper async functions it allows developers to use cleaner development practices in a lot of places. What do y'all think?
If I try to retrieve a user by their email address, I get an error. The docs make it appear as if we support this usage:
client.getUser('[email protected]')
.then(user => {
console.log(user);
});
The error says:
Error: only absolute urls are supported
Version: @okta/okta-sdk-nodejs: 4.2.0
Description: When deleting a user user can be retrieved but cannot be deactivated or deleted using the sample code from the README.
Test case
let okta = require('@okta/okta-sdk-nodejs');
function getOktaClient() {
const OKTA_TOKEN = '<<Redacted>>';
const OKTA_URL = 'https://example.okta.com/';
return new okta.Client({
orgUrl: OKTA_URL,
token: OKTA_TOKEN
});
}
async function deleteUser(email) {
const oktaClient = getOktaClient();
const oktaUser = await oktaClient.getUser(email);
console.log('User found');
console.dir(oktaUser);
return oktaUser.deactivate()
.then(() => console.log('OktaService: User ' + email + ' has been deactivated'));
.then(() => oktaUser.delete())
.then(() => console.log('OktaService: User ' + email + ' has been deleted'));
}
deleteUser('[email protected]').then(() => {
console.log('User deleted');
}).catch((ex) => {
console.log('Unable to delete \n' + ex);
});
Output
User found
User {
id: '00ugu38sc8YAWPCdF1t7',
status: 'DEPROVISIONED',
created: '2021-01-14T01:28:13.000Z',
activated: '2021-01-14T01:28:14.000Z',
statusChanged: '2021-01-14T23:49:43.000Z',
lastLogin: '2021-01-14T01:36:51.000Z',
lastUpdated: '2021-01-14T23:49:43.000Z',
passwordChanged: '2021-01-14T01:36:51.000Z',
type: UserType { id: 'oty1g30cq5iX3detP1t7' },
profile: UserProfile {
firstName: 'John Example',
lastName: 'unknown',
mobilePhone: '+1615555555',
secondEmail: null,
login: '[email protected]',
email: '[email protected]'
},
credentials: UserCredentials {
provider: AuthenticationProvider { type: 'OKTA', name: 'OKTA' }
},
_links: {
schema: {
href: 'https://example.okta.com/api/v1/meta/schemas/user/osc1g30cq5iX3detP1t7'
},
activate: {
href: 'https://example.okta.com/api/v1/users/00ugu38sc8YAWPCdF1t7/lifecycle/activate',
method: 'POST'
},
self: {
href: 'https://example.okta.com/api/v1/users/00ugu38sc8YAWPCdF1t7'
},
type: {
href: 'https://example.okta.com/api/v1/meta/types/user/oty1g30cq5iX3detP1t7'
},
delete: {
href: 'https://example.okta.com/api/v1/users/00ugu38sc8YAWPCdF1t7',
method: 'DELETE'
}
}
}
Unable to delete
OktaApiError: Okta HTTP 404 E0000007 Not found: Resource not found: 00ugu38sc8YAWPCdF1t7 (User).
We realized we needed to add some defensive programming on our end to make sure this doesn't happen, but it's likely something you could hopefully prevent for everyone else.
const Client = require('@okta/okta-sdk-nodejs');
const client = new Client.Client({ orgUrl: '//', token: '//' });
client.getUser('')
.then((response) => {
console.info({ response });
})
.catch((error) => {
console.error({ error });
});
Since this is a promise, I would expect this to reject with some error. Since it is a promise, it should resolve or reject or something.
The request happens in the background, but the promise never resolves or rejects. The script just runs and exits without ever logging anything.
Hi!
Maybe I'm missing something but how do we get all users in a specific group?
Thanks.
Is that possible to run script in parallel for multiple node platform? looks like it's running in sequence now
node_js:
- '10'
- '12'
A critical dependency of @okta/okta-sdk-nodejs, @okta/openapi, is not visible on GitHub. Even though documentation on NPM instructs users to clone that repository.
This PR is failing, despite it being a non-functional change: #83
Travis results: https://travis-ci.org/okta/okta-sdk-nodejs/jobs/462938531
Oddly, this only happens in the Node 8 tests.
Hi there!
I'm looking into updating a profile mapping for an IdP. I found that this is available through the API here, but don't find anything in the SDK for it. Taking a look at generated-client.js, I don't see anything that calls that url either
Are there plans to add this or any already open efforts? We will need to have this for our use case, so we will be building it out if not. We can contribute it back after 😀
Collection should wait the appropriate amount of time before fetching the next page as per X-Rate-Limit-Remaining
header.
For example, system logs sets the header to 120
. So there are a maximum of 120 requests to the API per minute. Collection
should thus wait 500ms before fetching the next page, so that per minute only a maximum of 120 requests will be made.
When using the node client to change a user password I get the following error message:
{
name: 'OktaApiError',
status: 400,
errorCode: 'E0000003',
errorSummary: 'The request body was not well-formed.',
}
Here's my code:
const okta = require('@okta/okta-sdk-nodejs');
const ChangePasswordRequest = require('@okta/okta-sdk-nodejs/src/models/ChangePasswordRequest');
const client = new okta.Client({
orgUrl: 'https://myorg.oktapreview.com/',
token: '00xmyToken'
});
const changePassword = ({ oktaUserId, oldPassword, newPassword }) => {
try {
client.changePassword(oktaUserId, new ChangePasswordRequest({ newPassword, oldPassword }))
.then(res => console.log(res))
.catch(err => console.error(err));
} catch (error) {
console.error(error.message)
}
}
changePassword({ oktaUserId: '00myUserId', oldPassword: 'myOldPassword', newPassword: 'myNewPassword' });
Am I missing something or is this broken?
Is there any wiki or docs on the factors api?
Requirements TBD, but generally: cache what resources we can in the spirit of reducing API calls when not needed.
The OAuth2 client credentials flow fails for clients with multiple JWK keys, when attempting to get an access token:
[OktaApiError: Okta HTTP 401 undefined ] {
status: 401,
errorCode: undefined,
errorSummary: '',
errorCauses: undefined,
errorLink: undefined,
errorId: undefined,
url: 'https://{DOMAIN}.okta.com/oauth2/v1/token',
headers: Headers {
[Symbol(map)]: [Object: null prototype] {
date: [Array],
server: [Array],
'content-type': [Array],
'x-okta-request-id': [Array],
'x-xss-protection': [Array],
p3p: [Array],
'x-rate-limit-limit': [Array],
'x-rate-limit-remaining': [Array],
'x-rate-limit-reset': [Array],
'cache-control': [Array],
pragma: [Array],
expires: [Array],
'expect-ct': [Array],
'x-content-type-options': [Array],
'strict-transport-security': [Array],
'set-cookie': [Array],
connection: [Array],
'transfer-encoding': [Array]
}
}
}
It appears that the API call to /oauth2/v1/token works with no issues for clients that only have one JWK (regardless of whether the JWK has a kid or not).
However, based on my tests, when multiple JWKs are configured for the same client, the API appears to accept only client_assertion JWTs that include the kid of the signing key in the header.
Unfortunately, the SDK does not offer a way to add a header to the signed JWT, so attempts to get a token fail with the error above.
If I modify the current implementation of https://github.com/okta/okta-sdk-nodejs/blob/master/src/jwt.js and add the following after line number 63,
.setHeader('kid', jwk.kid);
I am able to login and retrieve an access token. Please implement a way of adding the kid of the signing key in the JWT header, if needed.
Wanted to raise this against github.com/okta/openapi, but seeing as that's private, I figured this was the next best place.
The LogAuthenticationContext.credentialProvider
and LogAuthenticationContext.credentialType
are both specified as arrays in the OpenAPI spec, however the API docs (https://developer.okta.com/docs/reference/api/system-log/#logevent-object) and the API response itself returns one of an enumeration of strings or JSON null
.
This is affecting all the Okta SDK's I've looked at, so I expect no one is currently able to use the LogEvent API call successfully.
Java SDK: okta/okta-sdk-java#358
Go SDK: okta/okta-sdk-golang#65.
I'd be happy to make the openapi spec changes myself but since the repo is private there's not much I can do.
When you run the below code,
client.listUsers({
q: 'Robert'
}).each(user => {
console.log('User matches query: ', user);
});
if user(s) with property 'Robert' doesn't exist, listUsers()
returns an empty list.
But each()
is still executed once with an empty User object.
For example, the above code produces the following output in case user(s) with property 'Robert' doesn't exist -
User matches query: User {}
Ideally, in this case, there should be no output and the each()
loop shouldn't execute.
I am using getLogs
to get SystemLog records.
I noticed that the client
field in the resulting collection is the HTTP client used to fetch the SystemLog records, not the value of the client
field of the record itself.
I see you re-assign the client field of the json, so that the client field stores an HTTP client and It is used to allow resource models to execute http calls, like user.listUsers
.
This overwrites the client
field of LogEvent
.
okta-sdk-nodejs/src/resource.js
Line 19 in 8316026
okta-sdk-nodejs/src/models/LogEvent.js
Line 56 in 8316026
Besides not getting the actual data I need to use this actually opens up a major security issue since the HTTP client
field includes the API token information, which is a private secret and shouldn't be printed when I print a SystemLog record.
How can we delete an okta group using node sdk?
Attempting to make a call using the SDK method oktaClient.getUser(user)
. Ran into the title issue, realFetch.call is not a function
. Root seems to be in the latest version of isomorphic-fetch
lib issue here via node-fetch see here
Can the version be pinned to a lower version since it does seem to be present in just the latest, as mentioned here
I'm not sure if Node v4 ever worked. I get this when I try to interact with the client:
/node_modules/@okta/okta-sdk-nodejs/src/client.js:29
class Client extends GeneratedApiClient {
^^^^^
SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (/node_modules/@okta/okta-sdk-nodejs/src/index.js:15:11)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
It would be nice if there were TypeScript definitions for this SDK. Thanks!
The delete methods on the generated method are returning the raw http response object. To be consistent with other methods we should return the response body (which will be empty)
npm audit
reports handlebars High Vulnerability used in @okta/openapi.
handlebars has fix the issue in handlebars-lang/handlebars.js#1495
Has @okta/openapi pull the handlebars fix?
Where is the @okta/openapi repo?
package.json in this repo says version is 1.3.0, why is not published to npm?
If @okta/openapi has the fix, did 1.3.0 pull that in?
If not, can we raise the priority on this since it's a High Vulnerability and the fix is already in?
thanks.
Hi, I am trying to use okta-sdk in an app running on Next.js. However, I am having trouble initializing the client:
const okta = require('@okta/okta-sdk-nodejs');
produces
[ error ] ./node_modules/@okta/okta-sdk-nodejs/src/config-loader.js
Module not found: Can't resolve 'fs' in '/Users/home/app/node_modules/@okta/okta-sdk-nodejs/src'
Issues about fs
Next's repo (for example 7755, 9866) suggest adding:
module.exports = {
webpack: (config, { isServer }) => {
// Fixes npm packages that depend on `fs` module
if (!isServer) {
config.node = {
fs: 'empty'
}
}
return config
}
}
as the files read with fs
will only be available on server side, not during client rendering.
This solution fails because of the calls:
applyDefaults() {
const localYamlPath = path.join(process.cwd(), 'okta.yaml');
const globalYamlPath = path.join(os.homedir(), '.okta', 'okta.yaml');
if (fs.existsSync(globalYamlPath)) {
this.applyYamlFile(globalYamlPath);
}
if (fs.existsSync(localYamlPath)) {
this.applyYamlFile(localYamlPath);
}
this.applyEnvVars();
}
According to the docs, when creating a new client, a file okta.yaml
is searched in local directories before searching for environment variables or properties directly passed to the constructor. Is there a way to bypass the searching for files?
Thank you!
In our setup we needed to communicate with the okta services via a proxy. To achieve this we had to overwrite the Http implementation.
This is how we solved it:
const oktaSDK = require('@okta/okta-sdk-nodejs')
const Http = require('@okta/okta-sdk-nodejs/src/http')
const HttpsProxyAgent = require('https-proxy-agent')
class HttpWithProxy extends Http {
constructor({cacheStore, cacheMiddleware, defaultHeaders}) {
super({
cacheStore,
cacheMiddleware
})
this.defaultHeaders = defaultHeaders
// Okta is only https
const proxy = process.env.https_proxy || process.env.HTTPS_PROXY
if (proxy) {
logger.info(`Using proxy server ${proxy}`)
const agent = new HttpsProxyAgent(proxy)
this.agent = agent
}
}
http(uri, request, context) {
if (this.agent) {
request.agent = this.agent
}
return super.http(uri, request, context)
}
}
const oktaClient = new oktaSDK.Client({
orgUrl: 'https:...',
token: 'token'
})
oktaClient.http = new HttpWithProxy({defaultHeaders: oktaClient.http.defaultHeaders})
Could we extend the Client class to take in proxy configuration?
First off, just want to say awesome sdk! One quick thing i noticed is that is the first part of the readme docs on initialization a "," is missing.
referring to this below.
const client = new okta.Client({
orgUrl: 'https://dev-1234.oktapreview.com/'
token: 'xYzabc' // Obtained from Developer Dashboard
});
just a quick comma between them. Really is very minor, but just thought I would add.
To help avoid misconfiguration, this library should implement these checks against common errors: https://oktawiki.atlassian.net/wiki/spaces/PM/pages/552049922/Library+configuration+checks
For this library, checks against Okta domain (base URL) apply.
Hi,
I would like to use authorization code with PKCE from a Single Page App, get accessToken and explicitly pass accessToken to the SDK. This functionality is mainly for the CIAM Portals trying to update user credentials/attributes.
Thanks,
Praveen.
This code results in my script “hanging”, the script doesn’t seem to end? It executes correctly and returns user information, but then just hangs. After I run this, I have to ctrl + c to get back to the terminal.
const okta = require('@okta/okta-sdk-nodejs');
const client = new okta.Client({
orgUrl: 'https://dev-1234.oktapreview.com/'
token: 'xYzabc' // Obtained from Developer Dashboard
});
client.getUser('[email protected]')
.then(user => {
console.log(user);
});
Node v12.1.0
npm install @okta/okta-sdk-nodejs --save gives me following output:
/Users/g.reshetniak/.node-gyp/12.1.0/include/node/v8.h:2544:35: note: candidate function not viable: requires single argument 'isolate', but no arguments were provided
Local<String> ToString(Isolate* isolate) const);
^
../core.cc:97:19: warning: 'Call' is deprecated [-Wdeprecated-declarations]
callback->Call(0, NULL);
^
../../nan/nan.h:1673:3: note: 'Call' has been explicitly marked deprecated here
NAN_DEPRECATED inline v8::Local<v8::Value>
^
../../nan/nan.h:103:40: note: expanded from macro 'NAN_DEPRECATED'
# define NAN_DEPRECATED __attribute__((deprecated))
^
../core.cc:107:36: error: too few arguments to function call, single argument 'context' was not specified
int mask = info[0]->Int32Value();
~~~~~~~~~~~~~~~~~~~ ^
/Users/g.reshetniak/.node-gyp/12.1.0/include/node/v8.h:2569:3: note: 'Int32Value' declared here
V8_WARN_UNUSED_RESULT Maybe<int32_t> Int32Value(Local<Context> context) const;
^
/Users/g.reshetniak/.node-gyp/12.1.0/include/node/v8config.h:347:31: note: expanded from macro 'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
^
2 warnings and 9 errors generated.
make: *** [Release/obj.target/core/core.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack at ChildProcess.emit (events.js:196:13)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:256:12)
gyp ERR! System Darwin 17.7.0
gyp ERR! command "/usr/local/Cellar/node/12.1.0/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/g.reshetniak/okta-activator/node_modules/modern-syslog
gyp ERR! node -v v12.1.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm WARN [email protected] requires a peer of acorn@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/modern-syslog):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] install: `node-gyp rebuild`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1
+ @okta/[email protected]
updated 1 package in 12.544s
Not sure what is causing this, please advice.
Thanks.
no support to integrate authentication with node app using express
https://developer.okta.com/docs/reference/api/users/#get-current-user
The above method is not currently implemented in the node SDK, our service is currently calling this frequently through manual HTTP requests, even though we use other parts of this SDK.
It would be nice if the method was implemented, so we could unify our service.
Hi there! I'm looking to switch over to use your new typescript definitions (thank you! 😀) and am running into an issue.
My organization currently defines some custom attributes as part of the user profile. However, it looks to me like the UserProfile type has not way of accounting for these other attributes, which is causing my code that tries to access them to not compile.
I wanted to flag this and see if this is a known issue or if there's something I'm overlooking 😄
If this does need to be addressed, I'm not sure what would be a good strategy. Perhaps leveraging somehow generics on the User
/UserProfile
type to represent the custom properties?
Thank you!
It seems the https://developer.okta.com/docs/reference/api/users/#reactivate-user endpoint hasn't been implemented in the nodejs SDK.
Would it be possible to add it?
I'd give it a try myself but it seems that the repo for https://www.npmjs.com/package/@okta/openapi isn't public.
Thanks
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.