diff --git a/README.md b/README.md
index f7179a5..8aab19e 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-
lemon-web-core
+ LemonWebCore
- Shared library for LEMONCLOUD
+ LemonWebCore is a library designed for API requests and user authentication management in web-based projects for different cloud providers such as AWS, Azure, and GCP at LemonCloud.
@@ -18,33 +18,203 @@
---
-## Prerequisite
+## Table of Contents
-- [Node.js](https://nodejs.org/)
-- [pnpm](https://pnpm.io/)
+- [Installation](#installation)
+- [Usage](#usage)
+ - [WebCoreFactory](#webcorefactory)
+ - [AWSWebCore](#awswebcore)
+ - [AzureWebCore](#azurewebcore)
+- [API Reference](#api-reference)
+- [Troubleshooting](#troubleshooting)
-## Usage
+## Installation
-### Installation
+You can install the LemonWebCore Library via npm:
```bash
-$ git clone git@github.com:lemoncloud-io/lemon-web-core.git
-$ cd lemon-web-core
-$ pnpm install && pnpm prepare
+npm install @lemoncloud/lemon-web-core
```
-## Running the app
+## Usage
+
+The LemonWebCore Library allows you to create and use instances for different cloud providers. Below are the usage examples for WebCoreFactory, AWSWebCore, and AzureWebCore.
-```bash
-$ pnpm start
+### WebCoreFactory
+
+The `WebCoreFactory` is used to create instances of `AWSWebCore` or `AzureWebCore` based on the cloud provider configuration.
+
+- AWSWebCore
+
+```typescript
+import { WebCoreFactory, WebCoreConfig } from '@lemoncloud/lemon-web-core';
+
+const config: WebCoreConfig<'aws'> = {
+ cloud: 'aws',
+ project: 'my-aws-project',
+ oAuthEndpoint: 'https://example.com/oauth',
+ region: 'us-west-2',
+};
+const awsWebCore = WebCoreFactory.create(config);
+await awsWebCore.init();
```
-## Test
+- AzureWebCore
-```bash
-$ pnpm test
+```typescript
+const azureConfig: WebCoreConfig<'azure'> = {
+ cloud: 'azure',
+ project: 'my-azure-project',
+ oAuthEndpoint: 'https://example.com/oauth',
+};
+
+const azureWebCore = WebCoreFactory.create(azureConfig);
+await azureWebCore.init();
+```
+
+### AWSWebCore
+
+The `AWSWebCore` class handles AWS-specific web core operations. Here is an example of how to use it:
+
+```typescript
+import { AWSWebCore, WebCoreConfig } from '@lemoncloud/lemon-web-core';
+
+const config: WebCoreConfig<'aws'> = {
+ cloud: 'aws',
+ project: 'my-aws-project',
+ oAuthEndpoint: 'https://example.com/oauth',
+ region: 'us-west-2',
+};
+
+const awsWebCore = new AWSWebCore(config);
+
+// Initialize
+await awsWebCore.init();
+
+// Make a signed request
+const response = await awsWebCore.signedRequest('GET', 'https://example.com/api/resource');
+console.log(response.data);
+
+// Make a signed request with Builder
+const example = await awsWebCore
+ .buildSignedRequest({
+ method: 'GET',
+ baseURL: `https://api.lemoncloud.io/v1/oauth`,
+ })
+ .setParams({ page: 0 })
+ .setBody({ date: 'example' })
+ .execute();
+
+// Check authentication status
+const isAuthenticated = await awsWebCore.isAuthenticated();
+console.log(isAuthenticated);
+```
+
+### AzureWebCore
+
+The `AzureWebCore` class handles Azure-specific web core operations. Here is an example of how to use it:
+
+```typescript
+import { AzureWebCore, WebCoreConfig } from '@lemoncloud/lemon-web-core';
+
+const config: WebCoreConfig<'azure'> = {
+ cloud: 'azure',
+ project: 'my-azure-project',
+ oAuthEndpoint: 'https://example.com/oauth',
+};
+
+const azureWebCore = new AzureWebCore(config);
+
+// Initialize
+await azureWebCore.init();
+
+// Make a signed request
+const response = await azureWebCore.signedRequest('GET', 'https://example.com/api/resource');
+console.log(response.data);
+
+// Make a signed request with Builder
+const example = await azureWebCore
+ .buildSignedRequest({
+ method: 'GET',
+ baseURL: `https://api.lemoncloud.io/v1/oauth`,
+ })
+ .setParams({ page: 0 })
+ .setBody({ date: 'example' })
+ .execute();
+
+// Check authentication status
+const isAuthenticated = await azureWebCore.isAuthenticated();
+console.log(isAuthenticated);
```
+## API Reference
+
+### WebCoreFactory
+
+- `create(config: WebCoreConfig): T`
+
+Creates an instance of `AWSWebCore` or `AzureWebCore` based on the provided cloud provider configuration.
+
+### AWSWebCore
+
+- `constructor(config: WebCoreConfig<'aws'>)`
+
+Creates an instance of `AWSWebCore` with the specified configuration.
+
+- `init(): Promise`
+
+Initializes the AWSWebCore instance.
+
+- `signedRequest(method: string, url: string, params?: Params, body?: Body, config?: AxiosRequestConfig): Promise>`
+
+Makes a signed HTTP request.
+
+- `isAuthenticated(): Promise`
+
+Checks if the user is authenticated.
+
+- `saveOAuthToken(token: LemonOAuthToken): Promise`
+
+Saves the OAuth token.
+
+- `logout(): Promise`
+
+Logs the user out by clearing the OAuth token.
+
+- `setUseXLemonIdentity(use: boolean): Promise`
+
+Sets whether to use the x-lemon-identity header.
+
+### AzureWebCore
+
+- `constructor(config: WebCoreConfig<'azure'>)`
+
+Creates an instance of `AzureWebCore` with the specified configuration.
+
+- `init(): Promise`
+
+Initializes the AzureWebCore instance.
+
+- `signedRequest(method: string, url: string, params?: Params, body?: Body, config?: AxiosRequestConfig): Promise>`
+
+Makes a signed HTTP request.
+
+- `isAuthenticated(): Promise`
+
+Checks if the user is authenticated.
+
+- `saveOAuthToken(token: LemonOAuthToken): Promise`
+
+Saves the OAuth token.
+
+- `logout(): Promise`
+
+Logs the user out by clearing the OAuth token.
+
+- `setUseXLemonIdentity(use: boolean): Promise`
+
+Sets whether to use the x-lemon-identity header.
+
## Troubleshooting
Please follow this guidelines when reporting bugs and feature requests:
diff --git a/src/core/azure-web.core.ts b/src/core/azure-web.core.ts
index a16f10f..bf47411 100644
--- a/src/core/azure-web.core.ts
+++ b/src/core/azure-web.core.ts
@@ -1,23 +1,138 @@
-import { WebCoreConfig, WebCoreService } from '../types';
+import { AzureWebCoreState, Body, LemonOAuthToken, Params, WebCoreConfig, WebCoreService } from '../types';
+import { AzureStorageService, USE_X_LEMON_IDENTITY_KEY } from '../token-storage';
+import { LoggerService } from '../utils';
+import { AxiosRequestConfig, AxiosResponse } from 'axios';
+import { AzureHttpRequestBuilder } from '../http';
-// TODO: implment Azure Core
+/**
+ * Class to handle Azure-specific web core operations.
+ * Implements the WebCoreService interface.
+ */
export class AzureWebCore implements WebCoreService {
- constructor(private readonly config: WebCoreConfig<'azure'>) {}
- isAuthenticated(): Promise {
- return Promise.resolve(false);
+ private readonly tokenStorage: AzureStorageService;
+ private readonly logger: LoggerService;
+
+ /**
+ * Creates an instance of AzureWebCore.
+ * @param {WebCoreConfig<'azure'>} config - The configuration for the Azure web core.
+ */
+ constructor(private readonly config: WebCoreConfig<'azure'>) {
+ this.logger = new LoggerService('AzureCore');
+ this.logger.log('init AzureCore');
+ this.tokenStorage = new AzureStorageService(this.config);
}
- logout(): Promise {
- return;
+ /**
+ * Initializes the Azure web core by checking for cached tokens.
+ * @returns {Promise} - The state of the Azure web core after initialization.
+ */
+ async init(): Promise {
+ this.logger.log('initialize AzureCore');
+ const hasCachedToken = await this.tokenStorage.hasCachedToken();
+ if (!hasCachedToken) {
+ this.logger.warn('has no token!');
+ return 'no-token';
+ }
+
+ const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();
+ if (shouldRefreshToken) {
+ this.logger.info('should refresh token!');
+ // TODO: refresh azure token
+ }
+ return 'has-token';
+ }
+
+ /**
+ * Builds a signed request using the provided Axios configuration.
+ * @param {AxiosRequestConfig} config - The Axios request configuration.
+ * @returns {AzureHttpRequestBuilder} - The request builder for the signed request.
+ */
+ buildSignedRequest(config: AxiosRequestConfig): AzureHttpRequestBuilder {
+ return new AzureHttpRequestBuilder(this.tokenStorage, config);
+ }
+
+ /**
+ * Executes a signed HTTP request.
+ * @template T
+ * @param {string} method - The HTTP method to use for the request.
+ * @param {string} url - The URL for the request.
+ * @param {Params} [params={}] - The URL parameters for the request.
+ * @param {Body} [body] - The request body.
+ * @param {AxiosRequestConfig} [config] - Additional Axios request configuration.
+ * @returns {Promise>} - The Axios response.
+ */
+ async signedRequest(
+ method: string,
+ url: string,
+ params: Params = {},
+ body?: Body,
+ config?: AxiosRequestConfig
+ ): Promise> {
+ const builder = new AzureHttpRequestBuilder(this.tokenStorage, {
+ method,
+ baseURL: url,
+ params,
+ });
+ if (body) {
+ builder.setBody(body);
+ }
+ if (config) {
+ builder.addAxiosRequestConfig(config);
+ }
+ return await builder.execute();
}
- request(): Promise {
- return Promise.resolve(undefined);
+ /**
+ * Retrieves all saved tokens from the storage.
+ * @returns {Promise<{ [key: string]: string }>} - An object containing all saved tokens.
+ */
+ getSavedToken(): Promise<{ [key: string]: string }> {
+ return this.tokenStorage.getAllItems();
}
- setUseXLemonIdentity(): void {}
+ /**
+ * Checks if the user is authenticated.
+ * @returns {Promise} - True if authenticated, otherwise false.
+ */
+ async isAuthenticated(): Promise {
+ const hasCachedToken = await this.tokenStorage.hasCachedToken();
+ if (!hasCachedToken) {
+ return false;
+ }
+
+ const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();
+ if (shouldRefreshToken) {
+ this.logger.info('should refresh token!');
+ // TODO: refresh azure token
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Saves an OAuth token to the storage.
+ * @param {LemonOAuthToken} token - The OAuth token to save.
+ * @returns {Promise} - A promise that resolves when the token is saved.
+ */
+ async saveOAuthToken(token: LemonOAuthToken): Promise {
+ return await this.tokenStorage.saveOAuthToken(token);
+ }
+
+ /**
+ * Logs the user out by clearing the OAuth token from the storage.
+ * @returns {Promise} - A promise that resolves when the user is logged out.
+ */
+ async logout(): Promise {
+ await this.tokenStorage.clearOAuthToken();
+ return;
+ }
- getSavedToken(): Promise<{ [p: string]: string }> {
- return Promise.resolve({});
+ /**
+ * Sets whether to use the x-lemon-identity header.
+ * @param {boolean} use - True to use the x-lemon-identity header, otherwise false.
+ * @returns {Promise} - A promise that resolves when the setting is updated.
+ */
+ async setUseXLemonIdentity(use: boolean): Promise {
+ await this.tokenStorage.setItem(USE_X_LEMON_IDENTITY_KEY, `${use}`);
}
}
diff --git a/src/types/lemon.ts b/src/types/lemon.ts
index ff11eeb..3b3acc7 100644
--- a/src/types/lemon.ts
+++ b/src/types/lemon.ts
@@ -3,6 +3,11 @@
*/
export type AWSWebCoreState = 'no-token' | 'refreshed' | 'build';
+/**
+ * Represents the state of the Azure Web Core service.
+ */
+export type AzureWebCoreState = 'no-token' | 'has-token';
+
/**
* Represents the ARN of a KMS key in AWS.
*/