@cognite/sdk-core
Advanced tools
Comparing version 2.1.4 to 3.0.0-alpha
import { BaseResourceAPI } from '../../baseResourceApi'; | ||
import { CDFHttpClient } from '../../httpClient/cdfHttpClient'; | ||
import { IdInfo } from '../../auth'; | ||
import { IdInfo } from '../../authFlows/legacy'; | ||
import { MetadataMap } from '../../metadata'; | ||
@@ -11,2 +11,4 @@ export declare class LoginAPI extends BaseResourceAPI<any> { | ||
* | ||
* @deprecated | ||
* | ||
* ```js | ||
@@ -13,0 +15,0 @@ * const status = await client.login.status(); |
@@ -10,2 +10,4 @@ import { BaseResourceAPI } from '../../baseResourceApi'; | ||
* | ||
* @deprecated | ||
* | ||
* ```js | ||
@@ -12,0 +14,0 @@ * // You can specify the url to send the user to after the logout is successful. |
@@ -7,5 +7,7 @@ import { LoginAPI } from './api/login/loginApi'; | ||
import { RetryValidator } from './httpClient/retryValidator'; | ||
import { AzureAD, AzureADSignInType } from './aad'; | ||
import { OnAuthenticate, OnTokens } from './auth'; | ||
import { ADFS, ADFSRequestParams } from './adfs'; | ||
import { AzureAD, AzureADSignInType } from './authFlows/aad'; | ||
import { OnAuthenticate, OnTokens } from './authFlows/legacy'; | ||
import { ADFS, ADFSRequestParams } from './authFlows/adfs'; | ||
import { OIDCClientCredentialsFlowOptions } from './authFlows/oidc_client_credentials_flow'; | ||
import { OAuthLoginResult } from './types'; | ||
export interface ClientOptions { | ||
@@ -28,6 +30,22 @@ /** App identifier (ex: 'FileExtractor') */ | ||
} | ||
export declare const AAD_OAUTH = "AAD_OAUTH"; | ||
export declare const CDF_OAUTH = "CDF_OAUTH"; | ||
export declare const ADFS_OAUTH = "ADFS_OAUTH"; | ||
export declare type AuthFlowType = typeof AAD_OAUTH | typeof CDF_OAUTH | typeof ADFS_OAUTH; | ||
export declare type AAD_OAUTH = { | ||
type: 'AAD_OAUTH'; | ||
options: OAuthLoginForAADOptions; | ||
}; | ||
export declare type CDF_OAUTH = { | ||
type: 'CDF_OAUTH'; | ||
options: OAuthLoginForCogniteOptions; | ||
}; | ||
export declare type ADFS_OAUTH = { | ||
type: 'ADFS_OAUTH'; | ||
options: OAuthLoginForADFSOptions; | ||
}; | ||
export declare type OIDC_CLIENT_CREDENTIALS_FLOW = { | ||
type: 'OIDC_CLIENT_CREDENTIALS_FLOW'; | ||
options: OAuthLoginForOIDCVendorGenericFlowOptions; | ||
}; | ||
export declare type AuthFlowType = AAD_OAUTH | CDF_OAUTH | ADFS_OAUTH | OIDC_CLIENT_CREDENTIALS_FLOW; | ||
/** | ||
* @deprecated | ||
*/ | ||
export interface OAuthLoginForCogniteOptions { | ||
@@ -56,9 +74,9 @@ project: string; | ||
} | ||
export declare type OAuthLoginOptions = OAuthLoginForCogniteOptions | OAuthLoginForAADOptions | OAuthLoginForADFSOptions; | ||
export declare type OAuthLoginForOIDCVendorGenericFlowOptions = OIDCClientCredentialsFlowOptions; | ||
export declare function accessApi<T>(api: T | undefined): T; | ||
export declare function throwReLogginError(): void; | ||
declare type OAuthLoginResult = [() => Promise<boolean>, (string | null)]; | ||
export default class BaseCogniteClient { | ||
get login(): LoginAPI; | ||
get logout(): LogoutApi; | ||
private flow?; | ||
private readonly http; | ||
@@ -73,2 +91,3 @@ private readonly metadata; | ||
private cogniteAuthClient?; | ||
private vendorGenericFlowManager?; | ||
/** | ||
@@ -121,4 +140,7 @@ * Create a new SDK client | ||
* client.loginWithOAuth({ | ||
* project: '[PROJECT]', | ||
* onAuthenticate: REDIRECT // optional, REDIRECT is by default | ||
* type: 'CDF_OAUTH', | ||
* options: { | ||
* project: '[PROJECT]', | ||
* onAuthenticate: REDIRECT // optional, REDIRECT is by default | ||
* } | ||
* }); | ||
@@ -128,5 +150,8 @@ * | ||
* client.loginWithOAuth({ | ||
* cluster: '[CLUSTER]', | ||
* clientId: '[CLIENT_ID]', // client id of your AzureAD application | ||
* tenantId: '[TENANT_ID]', // tenant id of your AzureAD tenant. Will be set to 'common' if not provided | ||
* type: 'AAD_OAUTH', | ||
* options: { | ||
* cluster: '[CLUSTER]', | ||
* clientId: '[CLIENT_ID]', // client id of your AzureAD application | ||
* tenantId: '[TENANT_ID]', // tenant id of your AzureAD tenant. Will be set to 'common' if not provided | ||
* } | ||
* }); | ||
@@ -136,9 +161,22 @@ * | ||
* client.loginWithOAuth({ | ||
* authority: https://example.com/adfs/oauth2/authorize, | ||
* requestParams: { | ||
* cluster: 'cluster-name', | ||
* clientId: 'adfs-client-id', | ||
* }, | ||
* type: 'ADFS_OAUTH', | ||
* options: { | ||
* authority: https://example.com/adfs/oauth2/authorize, | ||
* requestParams: { | ||
* cluster: 'cluster-name', | ||
* clientId: 'adfs-client-id', | ||
* }, | ||
* } | ||
* }); | ||
* | ||
* // or with client credentials | ||
* client.loginWithOAuth({ | ||
* type: 'OIDC_CLIENT_CREDENTIALS_FLOW', | ||
* options: { | ||
* clientId: '[CLIENT_ID]', | ||
* clientSecret: '[CLIENT_SECRET]', | ||
* openIdConfigurationUrl: https://login.microsoftonline.com/[AZURE_TENANT_ID]/v2.0/.well-known/openid-configuration, | ||
* } | ||
* }); | ||
* | ||
* // after sign in you can do calls with the client | ||
@@ -154,3 +192,3 @@ * (async () => { | ||
*/ | ||
loginWithOAuth: (options: OAuthLoginOptions) => Promise<boolean>; | ||
loginWithOAuth: (flow: AuthFlowType) => Promise<boolean>; | ||
/** | ||
@@ -167,3 +205,3 @@ * To modify the base-url at any point in time | ||
*/ | ||
getOAuthFlowType(): AuthFlowType | undefined; | ||
getOAuthFlowType(): AuthFlowType['type'] | undefined; | ||
/** | ||
@@ -174,3 +212,3 @@ * Returns CDF token in case of AzureAD authentication flow usage. | ||
* ```js | ||
* client.loginWithOAuth({cluster: 'bluefield', ...}); | ||
* client.loginWithOAuth({ type: 'AAD_OAUTH', options: {cluster: 'bluefield', ...}}); | ||
* await client.authenticate(); | ||
@@ -186,3 +224,3 @@ * const cdfToken = await client.getCDFToken(); | ||
* ```js | ||
* client.loginWithOAuth({cluster: 'bluefield', ...}); | ||
* client.loginWithOAuth({ type: 'AAD_OAUTH', options: {cluster: 'bluefield', ...}); | ||
* await client.authenticate(); | ||
@@ -286,6 +324,5 @@ * const accessToken = await client.getAzureADAccessToken(); | ||
protected handleADFSLoginRedirect(adfsClient: ADFS): Promise<string | null>; | ||
protected validateAccessToken(token: string): Promise<boolean>; | ||
protected validateAccessToken: (token: string) => Promise<boolean>; | ||
} | ||
export declare type BaseRequestOptions = HttpRequestOptions; | ||
export declare type Response = HttpResponse<any>; | ||
export {}; |
@@ -19,1 +19,3 @@ /** @hidden */ | ||
export declare const X_REQUEST_ID = "X-Request-Id"; | ||
/** @hidden */ | ||
export declare const LOCAL_STORAGE_PREFIX = "@cognite/sdk:"; |
@@ -28,5 +28,5 @@ export declare class BasicHttpClient { | ||
getDefaultHeaders(): HttpHeaders; | ||
setBaseUrl(baseUrl: string): void; | ||
setBaseUrl: (baseUrl: string) => void; | ||
getBaseUrl(): string; | ||
setCluster(cluster: string): void; | ||
setCluster: (cluster: string) => void; | ||
get<ResponseType>(path: string, options?: HttpRequestOptions): Promise<HttpResponse<ResponseType>>; | ||
@@ -33,0 +33,0 @@ post<ResponseType>(path: string, options?: HttpRequestOptions): Promise<HttpResponse<ResponseType>>; |
@@ -13,3 +13,3 @@ import { HttpRequest, HttpResponse } from './basicHttpClient'; | ||
addOneTimeHeader(name: string, value: string): this; | ||
setBearerToken(token: string): void; | ||
setBearerToken: (token: string) => void; | ||
set401ResponseHandler(handler: Response401Handler): void; | ||
@@ -16,0 +16,0 @@ protected preRequest(request: HttpRequest): Promise<HttpRequest>; |
@@ -19,8 +19,8 @@ import * as Constants from './constants'; | ||
export { createUniversalRetryValidator, createRetryValidator, EndpointList, RetryValidator, } from './httpClient/retryValidator'; | ||
export { POPUP, REDIRECT, getIdInfo, AuthenticateParams, IdInfo, OnAuthenticateLoginObject, } from './auth'; | ||
export { POPUP, REDIRECT, getIdInfo, AuthenticateParams, IdInfo, OnAuthenticateLoginObject, } from './authFlows/legacy'; | ||
export { AuthorizeOptions, AuthorizeParams, AuthTokens, loginPopupHandler, getLogoutUrl, isLoginPopupWindow, } from './loginUtils'; | ||
export { RevertableArraySorter } from './revertableArraySorter'; | ||
export { sleepPromise, apiUrl, promiseAllAtOnce, promiseAllWithData, promiseEachInSequence, } from './utils'; | ||
export { AZURE_AUTH_POPUP, AZURE_AUTH_REDIRECT, AzureADSignInType, AzureADSingInFlow, AzureADSignInRequestParams, } from './aad'; | ||
export { ADFSRequestParams } from './adfs'; | ||
export { AZURE_AUTH_POPUP, AZURE_AUTH_REDIRECT, AzureADSignInType, AzureADSingInFlow, AzureADSignInRequestParams, } from './authFlows/aad'; | ||
export { ADFSRequestParams } from './authFlows/adfs'; | ||
export { TestUtils, Constants, GraphUtils }; |
@@ -89,1 +89,7 @@ export interface ListResponse<T> extends CursorResponse<T> { | ||
export declare type AutoPagingToArray<T> = (options?: AutoPagingToArrayOptions) => Promise<T[]>; | ||
export declare type OAuthLoginResult = [() => Promise<boolean>, (string | null)]; | ||
export interface FlowCallbacks { | ||
setCluster: (s: string) => void; | ||
setBearerToken: (s: string) => void; | ||
validateAccessToken: (s: string) => Promise<boolean>; | ||
} |
@@ -1,2 +0,1 @@ | ||
import { OAuthLoginForAADOptions, OAuthLoginForADFSOptions, OAuthLoginForCogniteOptions, OAuthLoginOptions } from './baseCogniteClient'; | ||
/** @hidden */ | ||
@@ -47,7 +46,1 @@ export declare function getBaseUrl(baseUrl?: string): string; | ||
export declare function isLocalhost(): boolean; | ||
/** @hidden */ | ||
export declare function isOAuthWithCogniteOptions(options: OAuthLoginOptions): options is OAuthLoginForCogniteOptions; | ||
/** @hidden */ | ||
export declare function isOAuthWithAADOptions(options: OAuthLoginOptions): options is OAuthLoginForAADOptions; | ||
/** @hidden **/ | ||
export declare function isOAuthWithADFSOptions(options: OAuthLoginOptions): options is OAuthLoginForADFSOptions; |
@@ -9,3 +9,3 @@ { | ||
"types": "dist/src/index.d.js", | ||
"version": "2.1.4", | ||
"version": "3.0.0-alpha", | ||
"scripts": { | ||
@@ -18,2 +18,3 @@ "clean": "rm -rf dist/ docs/", | ||
"build": "yarn clean && yarn rollup -c && yarn esCheck", | ||
"build:watch": "yarn rollup -w -c", | ||
"watch": "rollup -cw", | ||
@@ -29,2 +30,3 @@ "esCheck": "es-check es5 './dist/index.js'", | ||
"lodash": "^4.17.11", | ||
"openid-client": "^4.7.4", | ||
"query-string": "^5.1.1", | ||
@@ -38,4 +40,3 @@ "url": "^0.11.0" | ||
"@types/is-buffer": "^2.0.0" | ||
}, | ||
"gitHead": "cb9a69bd4e0d9b53538e2e3837a6cfeda4f224ce" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { AzureAD } from '../aad'; | ||
import { AzureAD } from '../authFlows/aad'; | ||
@@ -3,0 +3,0 @@ const getAccountByLocalId = jest.fn(); |
import nock from 'nock'; | ||
import noop from 'lodash/noop'; | ||
import { ADFS } from '../adfs'; | ||
import { ADFS } from '../authFlows/adfs'; | ||
import * as loginUtils from '../loginUtils'; | ||
@@ -5,0 +5,0 @@ |
@@ -6,3 +6,8 @@ // Copyright 2020 Cognite AS | ||
import { CDFHttpClient } from '../httpClient/cdfHttpClient'; | ||
import { CogniteAuthentication, getIdInfo, POPUP, REDIRECT } from '../auth'; | ||
import { | ||
CogniteAuthentication, | ||
getIdInfo, | ||
POPUP, | ||
REDIRECT, | ||
} from '../authFlows/legacy'; | ||
import * as LoginUtils from '../loginUtils'; | ||
@@ -9,0 +14,0 @@ import { getLogoutUrl, loginWithRedirect } from '../loginUtils'; |
// Copyright 2020 Cognite AS | ||
import nock from 'nock'; | ||
import BaseCogniteClient, { AAD_OAUTH, CDF_OAUTH } from '../baseCogniteClient'; | ||
import { POPUP, REDIRECT } from '../auth'; | ||
import BaseCogniteClient from '../baseCogniteClient'; | ||
import { POPUP, REDIRECT } from '../authFlows/legacy'; | ||
import { | ||
@@ -13,5 +13,6 @@ API_KEY_HEADER, | ||
import * as LoginUtils from '../loginUtils'; | ||
import { ADFS } from '../adfs'; | ||
import { ADFS } from '../authFlows/adfs'; | ||
import { bearerString, sleepPromise } from '../utils'; | ||
import { apiKey, authTokens, loggedInResponse, project } from '../testUtils'; | ||
import { TokenSet } from 'openid-client'; | ||
@@ -23,3 +24,3 @@ const initAuth = jest.fn(); | ||
jest.mock('../aad', () => { | ||
jest.mock('../authFlows/aad', () => { | ||
return { | ||
@@ -37,2 +38,18 @@ AzureAD: jest.fn().mockImplementation(() => { | ||
const openidInit = jest.fn(); | ||
const openidGetCDFToken = jest.fn(); | ||
const openidGetAuthTokens = jest.fn(); | ||
jest.mock('../authFlows/oidc_client_credentials_flow', () => { | ||
return { | ||
OidcClientCredentials: jest.fn().mockImplementation(() => { | ||
return { | ||
init: openidInit, | ||
getCDFToken: openidGetCDFToken, | ||
getAuthTokens: openidGetAuthTokens, | ||
}; | ||
}), | ||
}; | ||
}); | ||
const mockBaseUrl = 'https://example.com'; | ||
@@ -226,2 +243,8 @@ const cdfToken = 'azure-ad-CDF-token'; | ||
).rejects.toThrowErrorMatchingInlineSnapshot( | ||
`"\`loginWithOAuth\` is missing parameter \`flow\`"` | ||
); | ||
await expect( | ||
// @ts-ignore | ||
async () => await client.loginWithOAuth({ type: 'CDF_OAUTH' }) | ||
).rejects.toThrowErrorMatchingInlineSnapshot( | ||
`"\`loginWithOAuth\` is missing parameter \`options\`"` | ||
@@ -231,7 +254,8 @@ ); | ||
test('missing project name', async () => { | ||
test('invalid flow type', async () => { | ||
const client = setupClient(); | ||
await expect( | ||
// @ts-ignore | ||
async () => await client.loginWithOAuth({}) | ||
async () => | ||
// @ts-ignore | ||
await client.loginWithOAuth({ type: 'INVALID_FLOW', options: {} }) | ||
).rejects.toThrowErrorMatchingInlineSnapshot( | ||
@@ -262,3 +286,6 @@ `"\`loginWithOAuth\` is missing correct \`options\` structure"` | ||
const client = setupClient(); | ||
await client.loginWithOAuth({ project }); | ||
await client.loginWithOAuth({ | ||
type: 'CDF_OAUTH', | ||
options: { project }, | ||
}); | ||
mockRedirect.mockImplementationOnce(async () => { | ||
@@ -273,4 +300,7 @@ done(); | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate: POPUP, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate: POPUP, | ||
}, | ||
}); | ||
@@ -282,3 +312,3 @@ mockPopup.mockImplementationOnce(async () => { | ||
expect(client.getOAuthFlowType()).toEqual(CDF_OAUTH); | ||
expect(client.getOAuthFlowType()).toEqual('CDF_OAUTH'); | ||
}); | ||
@@ -289,4 +319,7 @@ | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate: REDIRECT, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate: REDIRECT, | ||
}, | ||
}); | ||
@@ -302,4 +335,7 @@ mockRedirect.mockImplementationOnce(async () => { | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate: POPUP, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate: POPUP, | ||
}, | ||
}); | ||
@@ -317,4 +353,7 @@ mockPopup.mockImplementationOnce(async () => { | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate, | ||
}, | ||
}); | ||
@@ -359,4 +398,7 @@ onAuthenticate.mockImplementation(login => { | ||
const isAuthenticated = await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate, | ||
}, | ||
}); | ||
@@ -390,4 +432,7 @@ | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate, | ||
}, | ||
}); | ||
@@ -406,4 +451,7 @@ await expect(client.authenticate()).resolves.toBe(false); | ||
const result = await client.loginWithOAuth({ | ||
project, | ||
onHandleRedirectError, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onHandleRedirectError, | ||
}, | ||
}); | ||
@@ -421,4 +469,7 @@ | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate: POPUP, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate: POPUP, | ||
}, | ||
}); | ||
@@ -451,4 +502,7 @@ nock(mockBaseUrl, { badheaders: [AUTHORIZATION_HEADER] }) | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate, | ||
}, | ||
}); | ||
@@ -474,4 +528,7 @@ nock(mockBaseUrl) | ||
await client.loginWithOAuth({ | ||
project, | ||
accessToken: authTokens.accessToken, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
accessToken: authTokens.accessToken, | ||
}, | ||
}); | ||
@@ -492,5 +549,8 @@ nock(mockBaseUrl, { | ||
await client.loginWithOAuth({ | ||
project, | ||
accessToken: authTokens.accessToken, | ||
onAuthenticate: () => done(), | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
accessToken: authTokens.accessToken, | ||
onAuthenticate: () => done(), | ||
}, | ||
}); | ||
@@ -507,6 +567,8 @@ nock(mockBaseUrl) | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate: POPUP, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate: POPUP, | ||
}, | ||
}); | ||
mockPopup.mockImplementationOnce(async () => { | ||
@@ -530,6 +592,8 @@ return { ...authTokens }; | ||
await client.loginWithOAuth({ | ||
project, | ||
onAuthenticate: POPUP, | ||
type: 'CDF_OAUTH', | ||
options: { | ||
project, | ||
onAuthenticate: POPUP, | ||
}, | ||
}); | ||
mockPopup.mockImplementationOnce(async () => { | ||
@@ -554,2 +618,44 @@ return { ...authTokens }; | ||
describe('authentication with client credentials', () => { | ||
const clientId = 'clientId'; | ||
const clientSecret = 'clientSecret'; | ||
const openIdConfigurationUrl = `https://login.microsoftonline.com/<TEST>/v2.0/.well-known/openid-configuration`; | ||
const cluster = 'test-cluster'; | ||
const scope = 'https://bluefield.cognitedata.com/.default'; | ||
const authenticate = jest.fn(); | ||
let client: BaseCogniteClient; | ||
beforeEach(() => { | ||
client = new BaseCogniteClient({ appId: 'test-app' }); | ||
}); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
test('should return true when authenticated', async () => { | ||
openidInit.mockResolvedValueOnce([authenticate, null]); | ||
authenticate.mockResolvedValueOnce(true); | ||
openidGetAuthTokens.mockResolvedValueOnce({ | ||
access_token: cdfToken, | ||
} as TokenSet); | ||
const result = await client.loginWithOAuth({ | ||
type: 'OIDC_CLIENT_CREDENTIALS_FLOW', | ||
options: { | ||
clientId, | ||
clientSecret, | ||
cluster, | ||
openIdConfigurationUrl, | ||
scope, | ||
}, | ||
}); | ||
expect(openidInit).toHaveBeenCalledTimes(1); | ||
expect(result).toEqual(false); | ||
const authenticateResult = await client.authenticate(); | ||
expect(authenticateResult).toEqual(true); | ||
}); | ||
}); | ||
describe('authentication with azure ad', () => { | ||
@@ -579,5 +685,8 @@ const clientId = 'clientId'; | ||
const result = await client.loginWithOAuth({ | ||
clientId, | ||
tenantId, | ||
cluster, | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
tenantId, | ||
cluster, | ||
}, | ||
}); | ||
@@ -598,6 +707,9 @@ | ||
await client.loginWithOAuth({ | ||
clientId, | ||
tenantId, | ||
cluster, | ||
signInType: { type: 'loginPopup' }, | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
tenantId, | ||
cluster, | ||
signInType: { type: 'loginPopup' }, | ||
}, | ||
}); | ||
@@ -619,5 +731,8 @@ | ||
const oAuthResult = await client.loginWithOAuth({ | ||
clientId, | ||
tenantId, | ||
cluster, | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
tenantId, | ||
cluster, | ||
}, | ||
}); | ||
@@ -638,5 +753,8 @@ const authResult = await client.authenticate(); | ||
const oAuthResult = await client.loginWithOAuth({ | ||
clientId, | ||
tenantId, | ||
cluster, | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
tenantId, | ||
cluster, | ||
}, | ||
}); | ||
@@ -660,3 +778,9 @@ | ||
const oAuthResult = await client.loginWithOAuth({ clientId, cluster }); | ||
const oAuthResult = await client.loginWithOAuth({ | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
cluster, | ||
}, | ||
}); | ||
@@ -684,3 +808,9 @@ const authResult = await client.authenticate(); | ||
const oAuthResult = await client.loginWithOAuth({ clientId, cluster }); | ||
const oAuthResult = await client.loginWithOAuth({ | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
cluster, | ||
}, | ||
}); | ||
const authResult = await client.authenticate(); | ||
@@ -702,10 +832,16 @@ | ||
await client.loginWithOAuth({ clientId, cluster }); | ||
await client.loginWithOAuth({ | ||
type: 'AAD_OAUTH', | ||
options: { clientId, cluster }, | ||
}); | ||
const result = await client.authenticate(); | ||
expect(result).toEqual(true); | ||
expect(client.getOAuthFlowType()).toEqual(AAD_OAUTH); | ||
expect(client.getOAuthFlowType()).toEqual('AAD_OAUTH'); | ||
}); | ||
test('should throw error on attempt to get Azure AD access token with cognite auth flow', async () => { | ||
await client.loginWithOAuth({ project }); | ||
await client.loginWithOAuth({ | ||
type: 'CDF_OAUTH', | ||
options: { project }, | ||
}); | ||
await expect( | ||
@@ -725,3 +861,6 @@ async () => await client.getAzureADAccessToken() | ||
await client.loginWithOAuth({ clientId, tenantId, cluster }); | ||
await client.loginWithOAuth({ | ||
type: 'AAD_OAUTH', | ||
options: { clientId, tenantId, cluster }, | ||
}); | ||
@@ -748,6 +887,9 @@ const result = await client.authenticate(); | ||
const result = await client.loginWithOAuth({ | ||
clientId, | ||
tenantId, | ||
cluster, | ||
onNoProjectAvailable, | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
tenantId, | ||
cluster, | ||
onNoProjectAvailable, | ||
}, | ||
}); | ||
@@ -770,7 +912,10 @@ | ||
const silentLogin = await client.loginWithOAuth({ | ||
clientId, | ||
tenantId, | ||
cluster, | ||
signInType: { type: 'loginPopup' }, | ||
onNoProjectAvailable, | ||
type: 'AAD_OAUTH', | ||
options: { | ||
clientId, | ||
tenantId, | ||
cluster, | ||
signInType: { type: 'loginPopup' }, | ||
onNoProjectAvailable, | ||
}, | ||
}); | ||
@@ -826,4 +971,7 @@ | ||
const result = await client.loginWithOAuth({ | ||
authority, | ||
requestParams, | ||
type: 'ADFS_OAUTH', | ||
options: { | ||
authority, | ||
requestParams, | ||
}, | ||
}); | ||
@@ -851,4 +999,7 @@ const cdfToken = await client.getCDFToken(); | ||
const result = await client.loginWithOAuth({ | ||
authority, | ||
requestParams, | ||
type: 'ADFS_OAUTH', | ||
options: { | ||
authority, | ||
requestParams, | ||
}, | ||
}); | ||
@@ -865,2 +1016,3 @@ | ||
const { location } = window; | ||
// @ts-ignore | ||
delete window.location; | ||
@@ -879,4 +1031,7 @@ window.location = { | ||
const result = await client.loginWithOAuth({ | ||
authority, | ||
requestParams, | ||
type: 'ADFS_OAUTH', | ||
options: { | ||
authority, | ||
requestParams, | ||
}, | ||
}); | ||
@@ -912,5 +1067,8 @@ | ||
const result = await client.loginWithOAuth({ | ||
authority, | ||
requestParams, | ||
onNoProjectAvailable, | ||
type: 'ADFS_OAUTH', | ||
options: { | ||
authority, | ||
requestParams, | ||
onNoProjectAvailable, | ||
}, | ||
}); | ||
@@ -934,5 +1092,8 @@ | ||
const result = await client.loginWithOAuth({ | ||
authority, | ||
requestParams, | ||
onNoProjectAvailable, | ||
type: 'ADFS_OAUTH', | ||
options: { | ||
authority, | ||
requestParams, | ||
onNoProjectAvailable, | ||
}, | ||
}); | ||
@@ -947,3 +1108,7 @@ const authenticated = await client.authenticate(); | ||
}); | ||
describe('authentication with oidc authorization code', () => { | ||
// TODO | ||
}); | ||
}); | ||
}); |
@@ -5,3 +5,3 @@ // Copyright 2020 Cognite AS | ||
import { CDFHttpClient } from '../../httpClient/cdfHttpClient'; | ||
import { getIdInfo, IdInfo } from '../../auth'; | ||
import { getIdInfo, IdInfo } from '../../authFlows/legacy'; | ||
import { MetadataMap } from '../../metadata'; | ||
@@ -18,2 +18,4 @@ | ||
* | ||
* @deprecated | ||
* | ||
* ```js | ||
@@ -20,0 +22,0 @@ * const status = await client.login.status(); |
@@ -17,2 +17,4 @@ // Copyright 2020 Cognite AS | ||
* | ||
* @deprecated | ||
* | ||
* ```js | ||
@@ -19,0 +21,0 @@ * // You can specify the url to send the user to after the logout is successful. |
@@ -24,5 +24,2 @@ // Copyright 2020 Cognite AS | ||
getBaseUrl, | ||
isOAuthWithAADOptions, | ||
isOAuthWithADFSOptions, | ||
isOAuthWithCogniteOptions, | ||
isUsingSSL, | ||
@@ -37,6 +34,15 @@ projectUrl, | ||
} from './httpClient/retryValidator'; | ||
import { AzureAD, AzureADSignInType } from './aad'; | ||
import { CogniteAuthentication, OnAuthenticate, OnTokens } from './auth'; | ||
import { AzureAD, AzureADSignInType } from './authFlows/aad'; | ||
import { | ||
CogniteAuthentication, | ||
OnAuthenticate, | ||
OnTokens, | ||
} from './authFlows/legacy'; | ||
import { ADFS, ADFSRequestParams } from './authFlows/adfs'; | ||
import { AuthTokens } from './loginUtils'; | ||
import { ADFS, ADFSRequestParams } from './adfs'; | ||
import { | ||
OidcClientCredentials, | ||
OIDCClientCredentialsFlowOptions, | ||
} from './authFlows/oidc_client_credentials_flow'; | ||
import { FlowCallbacks, OAuthLoginResult } from './types'; | ||
@@ -63,10 +69,27 @@ export interface ClientOptions { | ||
export const AAD_OAUTH = 'AAD_OAUTH'; | ||
export const CDF_OAUTH = 'CDF_OAUTH'; | ||
export const ADFS_OAUTH = 'ADFS_OAUTH'; | ||
export type AAD_OAUTH = { | ||
type: 'AAD_OAUTH'; | ||
options: OAuthLoginForAADOptions; | ||
}; | ||
export type CDF_OAUTH = { | ||
type: 'CDF_OAUTH'; | ||
options: OAuthLoginForCogniteOptions; | ||
}; | ||
export type ADFS_OAUTH = { | ||
type: 'ADFS_OAUTH'; | ||
options: OAuthLoginForADFSOptions; | ||
}; | ||
export type OIDC_CLIENT_CREDENTIALS_FLOW = { | ||
type: 'OIDC_CLIENT_CREDENTIALS_FLOW'; | ||
options: OAuthLoginForOIDCVendorGenericFlowOptions; | ||
}; | ||
export type AuthFlowType = | ||
| typeof AAD_OAUTH | ||
| typeof CDF_OAUTH | ||
| typeof ADFS_OAUTH; | ||
| AAD_OAUTH | ||
| CDF_OAUTH | ||
| ADFS_OAUTH | ||
| OIDC_CLIENT_CREDENTIALS_FLOW; | ||
/** | ||
* @deprecated | ||
*/ | ||
export interface OAuthLoginForCogniteOptions { | ||
@@ -98,6 +121,3 @@ project: string; | ||
export type OAuthLoginOptions = | ||
| OAuthLoginForCogniteOptions | ||
| OAuthLoginForAADOptions | ||
| OAuthLoginForADFSOptions; | ||
export type OAuthLoginForOIDCVendorGenericFlowOptions = OIDCClientCredentialsFlowOptions; | ||
@@ -119,4 +139,2 @@ export function accessApi<T>(api: T | undefined): T { | ||
type OAuthLoginResult = [() => Promise<boolean>, (string | null)]; | ||
export default class BaseCogniteClient { | ||
@@ -130,2 +148,4 @@ public get login() { | ||
private flow?: AuthFlowType; | ||
private readonly http: CDFHttpClient; | ||
@@ -140,2 +160,4 @@ private readonly metadata: MetadataMap; | ||
private cogniteAuthClient?: CogniteAuthentication; | ||
private vendorGenericFlowManager?: OidcClientCredentials; | ||
/** | ||
@@ -245,4 +267,7 @@ * Create a new SDK client | ||
* client.loginWithOAuth({ | ||
* project: '[PROJECT]', | ||
* onAuthenticate: REDIRECT // optional, REDIRECT is by default | ||
* type: 'CDF_OAUTH', | ||
* options: { | ||
* project: '[PROJECT]', | ||
* onAuthenticate: REDIRECT // optional, REDIRECT is by default | ||
* } | ||
* }); | ||
@@ -252,5 +277,8 @@ * | ||
* client.loginWithOAuth({ | ||
* cluster: '[CLUSTER]', | ||
* clientId: '[CLIENT_ID]', // client id of your AzureAD application | ||
* tenantId: '[TENANT_ID]', // tenant id of your AzureAD tenant. Will be set to 'common' if not provided | ||
* type: 'AAD_OAUTH', | ||
* options: { | ||
* cluster: '[CLUSTER]', | ||
* clientId: '[CLIENT_ID]', // client id of your AzureAD application | ||
* tenantId: '[TENANT_ID]', // tenant id of your AzureAD tenant. Will be set to 'common' if not provided | ||
* } | ||
* }); | ||
@@ -260,9 +288,22 @@ * | ||
* client.loginWithOAuth({ | ||
* authority: https://example.com/adfs/oauth2/authorize, | ||
* requestParams: { | ||
* cluster: 'cluster-name', | ||
* clientId: 'adfs-client-id', | ||
* }, | ||
* type: 'ADFS_OAUTH', | ||
* options: { | ||
* authority: https://example.com/adfs/oauth2/authorize, | ||
* requestParams: { | ||
* cluster: 'cluster-name', | ||
* clientId: 'adfs-client-id', | ||
* }, | ||
* } | ||
* }); | ||
* | ||
* // or with client credentials | ||
* client.loginWithOAuth({ | ||
* type: 'OIDC_CLIENT_CREDENTIALS_FLOW', | ||
* options: { | ||
* clientId: '[CLIENT_ID]', | ||
* clientSecret: '[CLIENT_SECRET]', | ||
* openIdConfigurationUrl: https://login.microsoftonline.com/[AZURE_TENANT_ID]/v2.0/.well-known/openid-configuration, | ||
* } | ||
* }); | ||
* | ||
* // after sign in you can do calls with the client | ||
@@ -278,5 +319,3 @@ * (async () => { | ||
*/ | ||
public loginWithOAuth = async ( | ||
options: OAuthLoginOptions | ||
): Promise<boolean> => { | ||
public loginWithOAuth = async (flow: AuthFlowType): Promise<boolean> => { | ||
let token = null; | ||
@@ -288,3 +327,6 @@ | ||
if (!options) { | ||
if (!flow || !flow.type) { | ||
throw Error('`loginWithOAuth` is missing parameter `flow`'); | ||
} | ||
if (!flow.options) { | ||
throw Error('`loginWithOAuth` is missing parameter `options`'); | ||
@@ -299,12 +341,38 @@ } | ||
this.flow = flow; | ||
let authenticate: () => Promise<boolean>; | ||
if (isOAuthWithCogniteOptions(options)) { | ||
[authenticate, token] = await this.loginWithCognite(options); | ||
} else if (isOAuthWithAADOptions(options)) { | ||
[authenticate, token] = await this.loginWithAAD(options); | ||
} else if (isOAuthWithADFSOptions(options)) { | ||
[authenticate, token] = await this.loginWithADFS(options); | ||
} else { | ||
throw Error('`loginWithOAuth` is missing correct `options` structure'); | ||
const callbacks: FlowCallbacks = { | ||
setCluster: this.httpClient.setCluster, | ||
setBearerToken: this.httpClient.setBearerToken, | ||
validateAccessToken: this.validateAccessToken, | ||
}; | ||
switch (flow.type) { | ||
case 'CDF_OAUTH': { | ||
[authenticate, token] = await this.loginWithCognite(flow.options); | ||
break; | ||
} | ||
case 'AAD_OAUTH': { | ||
[authenticate, token] = await this.loginWithAAD(flow.options); | ||
break; | ||
} | ||
case 'ADFS_OAUTH': { | ||
[authenticate, token] = await this.loginWithADFS(flow.options); | ||
break; | ||
} | ||
case 'OIDC_CLIENT_CREDENTIALS_FLOW': { | ||
[ | ||
authenticate, | ||
token, | ||
] = await (this.vendorGenericFlowManager = new OidcClientCredentials( | ||
flow.options, | ||
callbacks | ||
)).init(); | ||
break; | ||
} | ||
default: { | ||
throw Error('`loginWithOAuth` is missing correct `options` structure'); | ||
} | ||
} | ||
@@ -331,3 +399,7 @@ | ||
public setBaseUrl = (baseUrl: string) => { | ||
if (this.azureAdClient) { | ||
if ( | ||
this.flow && | ||
(this.flow.type === 'AAD_OAUTH' || | ||
this.flow.type === 'OIDC_CLIENT_CREDENTIALS_FLOW') | ||
) { | ||
throw Error('`setBaseUrl` does not available with Azure AD auth flow'); | ||
@@ -348,10 +420,4 @@ } | ||
*/ | ||
public getOAuthFlowType(): AuthFlowType | undefined { | ||
return this.azureAdClient | ||
? AAD_OAUTH | ||
: this.cogniteAuthClient | ||
? CDF_OAUTH | ||
: this.adfsClient | ||
? ADFS_OAUTH | ||
: undefined; | ||
public getOAuthFlowType(): AuthFlowType['type'] | undefined { | ||
return this.flow && this.flow.type; | ||
} | ||
@@ -364,3 +430,3 @@ | ||
* ```js | ||
* client.loginWithOAuth({cluster: 'bluefield', ...}); | ||
* client.loginWithOAuth({ type: 'AAD_OAUTH', options: {cluster: 'bluefield', ...}}); | ||
* await client.authenticate(); | ||
@@ -371,24 +437,29 @@ * const cdfToken = await client.getCDFToken(); | ||
public async getCDFToken(): Promise<string | null> { | ||
if (this.azureAdClient) { | ||
const token = await this.azureAdClient.getCDFToken(); | ||
if (token && !(await this.validateAccessToken(token))) { | ||
return null; | ||
switch (this.flow!.type) { | ||
case 'CDF_OAUTH': { | ||
const tokens = | ||
(await this.cogniteAuthClient!.getCDFToken(this.httpClient)) || null; | ||
return tokens ? tokens.accessToken : null; | ||
} | ||
case 'AAD_OAUTH': { | ||
const token = await this.azureAdClient!.getCDFToken(); | ||
return token; | ||
} else if (this.cogniteAuthClient) { | ||
const tokens = await this.cogniteAuthClient.getCDFToken(this.httpClient); | ||
return tokens ? tokens.accessToken : null; | ||
} else if (this.adfsClient) { | ||
const token = await this.adfsClient.getCDFToken(); | ||
if (token && !(await this.validateAccessToken(token))) { | ||
return null; | ||
if (token && !(await this.validateAccessToken(token))) { | ||
return null; | ||
} | ||
return token; | ||
} | ||
return token; | ||
} else { | ||
throw Error('CDF token can be acquired only using loginWithOAuth flow'); | ||
case 'ADFS_OAUTH': { | ||
const token = await this.adfsClient!.getCDFToken(); | ||
if (token && !(await this.validateAccessToken(token))) { | ||
return null; | ||
} | ||
return token; | ||
} | ||
case 'OIDC_CLIENT_CREDENTIALS_FLOW': { | ||
return this.vendorGenericFlowManager!.getCdfToken() || null; | ||
} | ||
default: { | ||
throw Error('CDF token can be acquired only using loginWithOAuth flow'); | ||
} | ||
} | ||
@@ -402,3 +473,3 @@ } | ||
* ```js | ||
* client.loginWithOAuth({cluster: 'bluefield', ...}); | ||
* client.loginWithOAuth({ type: 'AAD_OAUTH', options: {cluster: 'bluefield', ...}); | ||
* await client.authenticate(); | ||
@@ -762,3 +833,3 @@ * const accessToken = await client.getAzureADAccessToken(); | ||
protected async validateAccessToken(token: string): Promise<boolean> { | ||
protected validateAccessToken = async (token: string): Promise<boolean> => { | ||
try { | ||
@@ -779,3 +850,3 @@ const response = await this.httpClient.get<any>('/api/v1/token/inspect', { | ||
} | ||
} | ||
}; | ||
} | ||
@@ -782,0 +853,0 @@ |
@@ -22,1 +22,4 @@ // Copyright 2020 Cognite AS | ||
export const X_REQUEST_ID = 'X-Request-Id'; | ||
/** @hidden */ | ||
export const LOCAL_STORAGE_PREFIX = '@cognite/sdk:'; |
@@ -99,5 +99,5 @@ // Copyright 2020 Cognite AS | ||
public setBaseUrl(baseUrl: string) { | ||
public setBaseUrl = (baseUrl: string) => { | ||
this.baseUrl = baseUrl; | ||
} | ||
}; | ||
@@ -108,5 +108,5 @@ public getBaseUrl() { | ||
public setCluster(cluster: string) { | ||
public setCluster = (cluster: string) => { | ||
this.baseUrl = `https://${cluster}.${DEFAULT_DOMAIN}`; | ||
} | ||
}; | ||
@@ -113,0 +113,0 @@ public get<ResponseType>(path: string, options: HttpRequestOptions = {}) { |
@@ -71,5 +71,5 @@ // Copyright 2020 Cognite AS | ||
public setBearerToken(token: string) { | ||
public setBearerToken = (token: string) => { | ||
this.setDefaultHeader(AUTHORIZATION_HEADER, bearerString(token)); | ||
} | ||
}; | ||
@@ -76,0 +76,0 @@ public set401ResponseHandler(handler: Response401Handler) { |
@@ -41,3 +41,3 @@ // Copyright 2020 Cognite AS | ||
OnAuthenticateLoginObject, | ||
} from './auth'; | ||
} from './authFlows/legacy'; | ||
export { | ||
@@ -65,4 +65,4 @@ AuthorizeOptions, | ||
AzureADSignInRequestParams, | ||
} from './aad'; | ||
export { ADFSRequestParams } from './adfs'; | ||
} from './authFlows/aad'; | ||
export { ADFSRequestParams } from './authFlows/adfs'; | ||
export { TestUtils, Constants, GraphUtils }; |
@@ -113,1 +113,9 @@ // Copyright 2020 Cognite AS | ||
) => Promise<T[]>; | ||
export type OAuthLoginResult = [() => Promise<boolean>, (string | null)]; | ||
export interface FlowCallbacks { | ||
setCluster: (s: string) => void; | ||
setBearerToken: (s: string) => void; | ||
validateAccessToken: (s: string) => Promise<boolean>; | ||
} |
@@ -9,8 +9,2 @@ // Copyright 2020 Cognite AS | ||
import { CogniteMultiError } from './multiError'; | ||
import { | ||
OAuthLoginForAADOptions, | ||
OAuthLoginForADFSOptions, | ||
OAuthLoginForCogniteOptions, | ||
OAuthLoginOptions, | ||
} from './baseCogniteClient'; | ||
@@ -232,22 +226,1 @@ /** @hidden */ | ||
} | ||
/** @hidden */ | ||
export function isOAuthWithCogniteOptions( | ||
options: OAuthLoginOptions | ||
): options is OAuthLoginForCogniteOptions { | ||
return 'project' in options; | ||
} | ||
/** @hidden */ | ||
export function isOAuthWithAADOptions( | ||
options: OAuthLoginOptions | ||
): options is OAuthLoginForAADOptions { | ||
return ['clientId', 'cluster'].every(key => key in options); | ||
} | ||
/** @hidden **/ | ||
export function isOAuthWithADFSOptions( | ||
options: OAuthLoginOptions | ||
): options is OAuthLoginForADFSOptions { | ||
return ['authority', 'requestParams'].every(key => key in options); | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
470925
87
10340
7
1
3
+ Addedopenid-client@^4.7.4
+ Added@panva/asn1.js@1.0.0(transitive)
+ Added@sindresorhus/is@4.6.0(transitive)
+ Added@szmarczak/http-timer@4.0.6(transitive)
+ Added@types/cacheable-request@6.0.3(transitive)
+ Added@types/http-cache-semantics@4.0.4(transitive)
+ Added@types/keyv@3.1.4(transitive)
+ Added@types/node@22.9.0(transitive)
+ Added@types/responselike@1.0.3(transitive)
+ Addedaggregate-error@3.1.0(transitive)
+ Addedcacheable-lookup@5.0.4(transitive)
+ Addedcacheable-request@7.0.4(transitive)
+ Addedclean-stack@2.2.0(transitive)
+ Addedclone-response@1.0.3(transitive)
+ Addeddecompress-response@6.0.0(transitive)
+ Addeddefer-to-connect@2.0.1(transitive)
+ Addedend-of-stream@1.4.4(transitive)
+ Addedget-stream@5.2.0(transitive)
+ Addedgot@11.8.6(transitive)
+ Addedhttp-cache-semantics@4.1.1(transitive)
+ Addedhttp2-wrapper@1.0.3(transitive)
+ Addedindent-string@4.0.0(transitive)
+ Addedjose@2.0.7(transitive)
+ Addedjson-buffer@3.0.1(transitive)
+ Addedkeyv@4.5.4(transitive)
+ Addedlowercase-keys@2.0.0(transitive)
+ Addedlru-cache@6.0.0(transitive)
+ Addedmake-error@1.3.6(transitive)
+ Addedmimic-response@1.0.13.1.0(transitive)
+ Addednormalize-url@6.1.0(transitive)
+ Addedobject-hash@2.2.0(transitive)
+ Addedoidc-token-hash@5.0.3(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedopenid-client@4.9.1(transitive)
+ Addedp-cancelable@2.1.1(transitive)
+ Addedpump@3.0.2(transitive)
+ Addedquick-lru@5.1.1(transitive)
+ Addedresolve-alpn@1.2.1(transitive)
+ Addedresponselike@2.0.1(transitive)
+ Addedundici-types@6.19.8(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedyallist@4.0.0(transitive)