@brionmario-experimental/asgardeo-auth-spa
Version:
Asgardeo Auth SPA SDK to be used in Single-Page Applications.
320 lines (289 loc) • 12.1 kB
text/typescript
/**
* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
AsgardeoAuthClient,
AsgardeoAuthException,
AuthClientConfig,
BasicUserInfo
} from "@asgardeo/auth-js";
import { WebWorkerCore } from "./worker-core";
import {
DISABLE_HTTP_HANDLER,
ENABLE_HTTP_HANDLER,
GET_AUTH_URL,
GET_BASIC_USER_INFO,
GET_CONFIG_DATA,
GET_CRYPTO_HELPER,
GET_DECODED_ID_TOKEN,
GET_ID_TOKEN,
GET_OIDC_SERVICE_ENDPOINTS,
GET_SIGN_OUT_URL,
HTTP_REQUEST,
HTTP_REQUEST_ALL,
INIT,
IS_AUTHENTICATED,
REFRESH_ACCESS_TOKEN,
REQUEST_ACCESS_TOKEN,
REQUEST_CUSTOM_GRANT,
REQUEST_FINISH,
REQUEST_START,
REQUEST_SUCCESS,
REVOKE_ACCESS_TOKEN,
SET_SESSION_STATE,
SIGN_OUT,
START_AUTO_REFRESH_TOKEN,
UPDATE_CONFIG
} from "../constants";
import { AuthenticationHelper, SPAHelper } from "../helpers";
import {
AuthorizationResponse,
HttpResponse,
WebWorkerClass,
WebWorkerClientConfig,
WebWorkerCoreInterface
} from "../models";
import { MessageUtils } from "../utils";
export const workerReceiver = (
getAuthHelper: (
authClient: AsgardeoAuthClient<WebWorkerClientConfig>,
spaHelper: SPAHelper<WebWorkerClientConfig>
) => AuthenticationHelper<WebWorkerClientConfig>
) => {
const ctx: WebWorkerClass<any> = self as any;
let webWorker: WebWorkerCoreInterface;
ctx.onmessage = async ({ data, ports }) => {
const port = ports[0];
if (data.type !== INIT && !webWorker) {
port.postMessage(
MessageUtils.generateFailureMessage(
new AsgardeoAuthException(
"SPA-CLIENT_WORKER-ONMSG-NF01",
"The web worker has not been initialized yet.",
"The initialize method needs to be called before the specified operation can be carried out."
)
)
);
return;
}
switch (data.type) {
case INIT:
try {
const config: AuthClientConfig<WebWorkerClientConfig> = { ...data.data };
webWorker = await WebWorkerCore(config, getAuthHelper);
webWorker.setHttpRequestFinishCallback(onRequestFinishCallback);
webWorker.setHttpRequestStartCallback(onRequestStartCallback);
webWorker.setHttpRequestSuccessCallback(onRequestSuccessCallback);
port.postMessage(MessageUtils.generateSuccessMessage());
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_AUTH_URL:
webWorker
.getAuthorizationURL(data?.data)
.then((response: AuthorizationResponse) => {
port.postMessage(MessageUtils.generateSuccessMessage(response));
})
.catch((error) => {
port.postMessage(MessageUtils.generateFailureMessage(error));
});
break;
case REQUEST_ACCESS_TOKEN:
webWorker
.requestAccessToken(data?.data?.code, data?.data?.sessionState, data?.data?.pkce, data?.data?.state)
.then((response: BasicUserInfo) => {
port.postMessage(MessageUtils.generateSuccessMessage(response));
})
.catch((error) => {
port.postMessage(MessageUtils.generateFailureMessage(error));
});
break;
case HTTP_REQUEST: {
const request = data.data;
const requestData = request?.data;
if(data.data?.data?.formData === true) {
const formData = new FormData();
for (const key in requestData) {
if(key === "formData") {
continue;
}
formData.append(key, requestData[key])
}
request.data = formData;
}
webWorker
.httpRequest(request)
.then((response) => {
port.postMessage(MessageUtils.generateSuccessMessage(response));
})
.catch((error) => {
port.postMessage(MessageUtils.generateFailureMessage(error));
});
break;
}
case HTTP_REQUEST_ALL:
webWorker
.httpRequestAll(data.data)
.then((response) => {
port.postMessage(MessageUtils.generateSuccessMessage(response));
})
.catch((error) => {
port.postMessage(MessageUtils.generateFailureMessage(error));
});
break;
case SIGN_OUT:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.signOut()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case REQUEST_CUSTOM_GRANT:
webWorker
.requestCustomGrant(data.data)
.then((response) => {
port.postMessage(MessageUtils.generateSuccessMessage(response));
})
.catch((error) => {
port.postMessage(MessageUtils.generateFailureMessage(error));
});
break;
case REVOKE_ACCESS_TOKEN:
webWorker
.revokeAccessToken()
.then((response) => {
port.postMessage(MessageUtils.generateSuccessMessage(response));
})
.catch((error) => {
port.postMessage(MessageUtils.generateFailureMessage(error));
});
break;
case GET_OIDC_SERVICE_ENDPOINTS:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getOIDCServiceEndpoints()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_BASIC_USER_INFO:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getBasicUserInfo()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_DECODED_ID_TOKEN:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getDecodedIDToken()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_CRYPTO_HELPER:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getCryptoHelper()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_ID_TOKEN:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getIDToken()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case ENABLE_HTTP_HANDLER:
webWorker.enableHttpHandler();
port.postMessage(MessageUtils.generateSuccessMessage());
break;
case DISABLE_HTTP_HANDLER:
webWorker.disableHttpHandler();
port.postMessage(MessageUtils.generateSuccessMessage());
break;
case IS_AUTHENTICATED:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.isAuthenticated()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_SIGN_OUT_URL:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getSignOutURL()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case REFRESH_ACCESS_TOKEN:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.refreshAccessToken()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case START_AUTO_REFRESH_TOKEN:
try {
port.postMessage(MessageUtils.generateSuccessMessage(webWorker.startAutoRefreshToken()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case SET_SESSION_STATE:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.setSessionState(data?.data)));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case UPDATE_CONFIG:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.updateConfig(data?.data)));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
case GET_CONFIG_DATA:
try {
port.postMessage(MessageUtils.generateSuccessMessage(await webWorker.getConfigData()));
} catch (error) {
port.postMessage(MessageUtils.generateFailureMessage(error));
}
break;
default:
port?.postMessage(
MessageUtils.generateFailureMessage(
new AsgardeoAuthException(
"SPA-CLIENT_WORKER-ONMSG-IV02",
"The message type is invalid.",
`The message type provided, ${data.type}, is invalid.`
)
)
);
}
};
const onRequestStartCallback = (): void => {
ctx.postMessage({ type: REQUEST_START });
};
const onRequestSuccessCallback = (response: HttpResponse): void => {
ctx.postMessage({ data: JSON.stringify(response ?? ""), type: REQUEST_SUCCESS });
};
const onRequestFinishCallback = (): void => {
ctx.postMessage({ type: REQUEST_FINISH });
};
};