Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom params for token request via sign-in method #174

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ auth.getBasicUserInfo().then((response) => {
### signIn

```typescript
signIn(config?: SignInConfig, authorizationCode?: string, sessionState?: string);
signIn(config?: SignInConfig, authorizationCode?: string, sessionState?: string, tokenRequestConfig?: { params: Record<string, unknown> });
```

#### Arguments
Expand All @@ -346,6 +346,15 @@ signIn(config?: SignInConfig, authorizationCode?: string, sessionState?: string)
The `signIn` method can be passed the authorization code as an argument, which will be used to obtain the token during the token-request phase of the method. This allows developers to use different response modes such as `form_post`. To learn more about the `form_post` method refer to the [Using the `form_post` response mode](#Using-the-form_post-response-mode) section. If you're using the `query` method, then the `signIn` method automatically obtains the authorization code from the URL.
3. sessionState?: `string` (optional)
The `signIn` method can be passed the session state as an argument, which will be used to obtain the token during the token-request phase of the method. This allows developers to use different response modes such as `form_post`. To learn more about the `form_post` method refer to the [Using the `form_post` response mode](#Using-the-form_post-response-mode) section. If you're using the `query` method, then the `signIn` method automatically obtains the session state from the URL.
4. tokenRequestConfig?: `object` (optional)
An optional configuration object that allows you to augment the token request.
- `params` (Mandatory): Key-value pairs to be sent as additional parameters in the token request payload.

```TypeScript
tokenRequestConfig: {
params: Record<string, unknown>
}
```

#### Description

Expand Down
2 changes: 1 addition & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"author": "Asgardeo",
"license": "Apache-2.0",
"dependencies": {
"@asgardeo/auth-js": "^5.0.0",
"@asgardeo/auth-js": "^5.1.0",
"await-semaphore": "^0.1.3",
"axios": "^0.26.0",
"base64url": "^3.0.1",
Expand Down
20 changes: 12 additions & 8 deletions lib/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,10 @@ export class AsgardeoSPAClient {
config?: SignInConfig,
authorizationCode?: string,
sessionState?: string,
state?: string
state?: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo | undefined> {
await this._isInitialized();

Expand All @@ -384,15 +387,16 @@ export class AsgardeoSPAClient {

delete config?.callOnlyOnRedirect;

return this._client?.signIn(config, authorizationCode, sessionState, state).then((response: BasicUserInfo) => {
if (this._onSignInCallback) {
if (response.allowedScopes || response.displayName || response.email || response.username) {
this._onSignInCallback(response);
return this._client?.signIn(config, authorizationCode, sessionState, state, tokenRequestConfig)
.then((response: BasicUserInfo) => {
if (this._onSignInCallback) {
if (response.allowedScopes || response.displayName || response.email || response.username) {
this._onSignInCallback(response);
}
}
}

return response;
});
return response;
});
}

/**
Expand Down
33 changes: 27 additions & 6 deletions lib/src/clients/main-thread-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ import {
} from "@asgardeo/auth-js";
import {
SILENT_SIGN_IN_STATE,
Storage
Storage,
TOKEN_REQUEST_CONFIG_KEY
} from "../constants";
import { AuthenticationHelper, SPAHelper, SessionManagementHelper } from "../helpers";
import { HttpClient, HttpClientInstance } from "../http-client";
Expand Down Expand Up @@ -188,12 +189,16 @@ export const MainThreadClient = async (
signInConfig?: GetAuthURLConfig,
authorizationCode?: string,
sessionState?: string,
state?: string
state?: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo> => {

const basicUserInfo = await _authenticationHelper.handleSignIn(
shouldStopAuthn,
checkSession
checkSession,
undefined
);

if(basicUserInfo) {
Expand All @@ -202,6 +207,9 @@ export const MainThreadClient = async (
let resolvedAuthorizationCode: string;
let resolvedSessionState: string;
let resolvedState: string;
let resolvedTokenRequestConfig: {
params: Record<string, unknown>
} = { params: {} };

if (config?.responseMode === ResponseMode.formPost && authorizationCode) {
resolvedAuthorizationCode = authorizationCode;
Expand All @@ -217,7 +225,12 @@ export const MainThreadClient = async (

if (resolvedAuthorizationCode && resolvedState) {
setSessionStatus("true");
return requestAccessToken(resolvedAuthorizationCode, resolvedSessionState, resolvedState);
const storedTokenRequestConfig = await _dataLayer.getTemporaryDataParameter(TOKEN_REQUEST_CONFIG_KEY);
if (storedTokenRequestConfig && typeof storedTokenRequestConfig === "string") {
resolvedTokenRequestConfig = JSON.parse(storedTokenRequestConfig);
}
return requestAccessToken(resolvedAuthorizationCode, resolvedSessionState,
resolvedState, resolvedTokenRequestConfig);
}

return _authenticationClient.getAuthorizationURL(signInConfig).then(async (url: string) => {
Expand All @@ -227,6 +240,10 @@ export const MainThreadClient = async (
SPAUtils.setPKCE(pkceKey, (await _authenticationClient.getPKCECode(resolvedState)) as string);
}

if (tokenRequestConfig) {
_dataLayer.setTemporaryDataParameter(TOKEN_REQUEST_CONFIG_KEY, JSON.stringify(tokenRequestConfig));
}

location.href = url;

await SPAUtils.waitTillPageRedirect();
Expand Down Expand Up @@ -304,14 +321,18 @@ export const MainThreadClient = async (
const requestAccessToken = async (
resolvedAuthorizationCode: string,
resolvedSessionState: string,
resolvedState: string
resolvedState: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo> => {
return await _authenticationHelper.requestAccessToken(
resolvedAuthorizationCode,
resolvedSessionState,
checkSession,
undefined,
resolvedState
resolvedState,
tokenRequestConfig
);
};

Expand Down
16 changes: 12 additions & 4 deletions lib/src/clients/web-worker-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,10 @@ export const WebWorkerClient = async (
const requestAccessToken = async (
resolvedAuthorizationCode: string,
resolvedSessionState: string,
resolvedState: string
resolvedState: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo> => {
const config: AuthClientConfig<WebWorkerClientConfig> = await getConfigData();
const pkceKey: string = AuthenticationUtils.extractPKCEKeyFromStateParam(resolvedState);
Expand All @@ -483,7 +486,8 @@ export const WebWorkerClient = async (
code: resolvedAuthorizationCode,
pkce: config.enablePKCE ? SPAUtils.getPKCE(pkceKey) : undefined,
sessionState: resolvedSessionState,
state: resolvedState
state: resolvedState,
tokenRequestConfig
},
type: REQUEST_ACCESS_TOKEN
};
Expand Down Expand Up @@ -548,7 +552,10 @@ export const WebWorkerClient = async (
params?: GetAuthURLConfig,
authorizationCode?: string,
sessionState?: string,
state?: string
state?: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo> => {

const basicUserInfo = await _authenticationHelper.handleSignIn(
Expand Down Expand Up @@ -577,7 +584,8 @@ export const WebWorkerClient = async (
}

if (resolvedAuthorizationCode && resolvedState) {
return requestAccessToken(resolvedAuthorizationCode, resolvedSessionState, resolvedState);
return requestAccessToken(resolvedAuthorizationCode, resolvedSessionState,
resolvedState, tokenRequestConfig);
}

return getAuthorizationURL(params)
Expand Down
2 changes: 2 additions & 0 deletions lib/src/constants/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ export enum Storage {
WebWorker = "webWorker",
BrowserMemory = "browserMemory"
}

export const TOKEN_REQUEST_CONFIG_KEY = "token_request_config";
7 changes: 5 additions & 2 deletions lib/src/helpers/authentication-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,10 @@ export class AuthenticationHelper<
sessionState?: string,
checkSession?: () => Promise<void>,
pkce?: string,
state?: string
state?: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo> {
const config = await this._dataLayer.getConfigData();

Expand All @@ -490,7 +493,7 @@ export class AuthenticationHelper<

if (authorizationCode) {
return this._authenticationClient
.requestAccessToken(authorizationCode, sessionState ?? "", state ?? "")
.requestAccessToken(authorizationCode, sessionState ?? "", state ?? "", undefined, tokenRequestConfig)
.then(async () => {
// Disable this temporarily
/* if (config.storage === Storage.BrowserMemory) {
Expand Down
10 changes: 8 additions & 2 deletions lib/src/models/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ export interface MainThreadClientInterface {
config?: SignInConfig,
authorizationCode?: string,
sessionState?: string,
signInRedirectURL?: string
signInRedirectURL?: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo>;
signOut(signOutRedirectURL?: string): Promise<boolean>;
requestCustomGrant(config: CustomGrantConfig): Promise<BasicUserInfo | FetchResponse>;
Expand Down Expand Up @@ -80,7 +83,10 @@ export interface WebWorkerClientInterface {
params?: SignInConfig,
authorizationCode?: string,
sessionState?: string,
signInRedirectURL?: string
signInRedirectURL?: string,
tokenRequestConfig?: {
params: Record<string, unknown>
}
): Promise<BasicUserInfo>;
signOut(signOutRedirectURL?: string): Promise<boolean>;
revokeAccessToken(): Promise<boolean>;
Expand Down
3 changes: 3 additions & 0 deletions lib/src/models/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export interface AuthorizationInfo {
sessionState: string;
pkce?: string;
state: string;
tokenRequestConfig?: {
params: Record<string, unknown>
}
}

export type MessageType =
Expand Down
8 changes: 4 additions & 4 deletions lib/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"@jridgewell/gen-mapping" "^0.1.0"
"@jridgewell/trace-mapping" "^0.3.9"

"@asgardeo/auth-js@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@asgardeo/auth-js/-/auth-js-5.0.0.tgz#ad63c232ac0588363e95c54d576c6318a6d4be93"
integrity sha512-BMQsTzpFwtgbSeJvmSDgRrOjXfA6+yQ2NUq7CXP4q1TtqZJt8s/zadOazPM00/jIY8B2ENS0CLRHp07M0mFdOw==
"@asgardeo/auth-js@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@asgardeo/auth-js/-/auth-js-5.1.0.tgz#4a5b129ae247f330ab534f0fcb33e0145bf17f26"
integrity sha512-o+bo3r9RDo97CqEAFpneYIGdulBRUbdjR6QhZgF89zy3rnss1U1MA2v2heMwXKNbMfvbZCBiBDq2yhUcAk9SIA==

"@babel/cli@^7.17.6":
version "7.18.9"
Expand Down
Loading