diff --git a/.github/workflows/release-docs.yml b/.github/workflows/release-docs.yml
index 5256a0e8b3..eb52fe581e 100644
--- a/.github/workflows/release-docs.yml
+++ b/.github/workflows/release-docs.yml
@@ -90,22 +90,35 @@ jobs:
- name: Build MkDocs Documentation
run: |
+ unset ENABLE_HOOKS
cd en/asgardeo
mkdocs build
cd ../../
+ - name: Conditionally build MkDocs Documentation
+ run: |
+ export ENABLE_HOOKS=true
+ cd en/asgardeo
+ mkdocs build --site-dir prod-build
+ cd ../../
+
- name: Zip the Documentation
run: |
mkdir -p out/asgardeo/docs
+ mkdir -p out-prod/asgardeo/docs
cp -r ./en/asgardeo/site/* out/asgardeo/docs/
+ cp -r ./en/asgardeo/prod-build/* out-prod/asgardeo/docs/
zip -r asgardeo-docs-${{ env.NEW_VERSION }}.zip ./out
+ zip -r asgardeo-docs-${{ env.NEW_VERSION }}-prod.zip ./out-prod
- name: Create git tag
run: |
git config user.name $GIT_USERNAME
git config user.email $GIT_USER_EMAIL
git tag "v${{ env.NEW_VERSION }}"
+ git tag "v${{ env.NEW_VERSION }}-prod"
git push "https://$GIT_USERNAME:$GITHUB_TOKEN@github.com/${{ github.repository }}" "v${{ env.NEW_VERSION }}"
+ git push "https://$GIT_USERNAME:$GITHUB_TOKEN@github.com/${{ github.repository }}" "v${{ env.NEW_VERSION }}-prod"
- name: Create Release
id: create_release
@@ -115,6 +128,15 @@ jobs:
release_name: Asgardeo Docs - v${{ env.NEW_VERSION }}
draft: false
prerelease: ${{ env.IS_HOTFIX == 'true' }}
+
+ - name: Create prod release
+ id: create_prod_release
+ uses: actions/create-release@v1
+ with:
+ tag_name: v${{ env.NEW_VERSION }}-prod
+ release_name: Asgardeo Docs - v${{ env.NEW_VERSION }}-prod
+ draft: false
+ prerelease: ${{ env.IS_HOTFIX == 'true' }}
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
@@ -123,6 +145,14 @@ jobs:
asset_path: ./asgardeo-docs-${{ env.NEW_VERSION }}.zip
asset_name: asgardeo-docs-${{ env.NEW_VERSION }}.zip
asset_content_type: application/zip
+
+ - name: Upload Prod Release Asset
+ uses: actions/upload-release-asset@v1
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: ./asgardeo-docs-${{ env.NEW_VERSION }}-prod.zip
+ asset_name: asgardeo-docs-${{ env.NEW_VERSION }}-prod.zip
+ asset_content_type: application/zip
- name: Commit and push new version
if: ${{ env.IS_HOTFIX == 'false' }}
diff --git a/VERSION b/VERSION
index 87df0737be..1887e7e668 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.270
+0.0.275
diff --git a/en/asgardeo/docs/apis/restapis/rule-metadata.yaml b/en/asgardeo/docs/apis/restapis/rule-metadata.yaml
new file mode 100644
index 0000000000..665cad186b
--- /dev/null
+++ b/en/asgardeo/docs/apis/restapis/rule-metadata.yaml
@@ -0,0 +1,369 @@
+openapi: 3.0.1
+info:
+ title: Asgardeo Rule Metadata REST API
+ description: "The Rule Metadata API provides the essential metadata required to configure rules dynamically based on the flow context. \nThe metadata retrieved by this API is designed to support rule configuration in the user interface (UI) by delivering information about each configurable field, the set of applicable comparison operators (e.g., equals, contains) for each field, and lists of possible values or options for fields.\n"
+ contact:
+ name: WSO2
+ url: https://wso2.com/identity-and-access-management/
+ license:
+ name: Apache 2.0
+ url: https://www.apache.org/licenses/LICENSE-2.0.html
+ version: v1
+servers:
+ - url: 'https://api.asgardeo.io/t/{organization-name}/api/server/v1'
+security:
+- OAuth2: []
+paths:
+ /rules/metadata:
+ get:
+ tags:
+ - Metadata
+ summary: Get metadata for rule configuration.
+ description: |+
+ This API provides a list of fields, associated metadata, and applicable operators for each field based on the specified flow type. This information is used to populate the UI for rule configuration.
+
+ Scope (Permission) required: ``internal_rule_metadata_view``
+
+ operationId: getExpressionMeta
+ parameters:
+ - name: flow
+ in: query
+ description: |
+ Specifies the flow to retrieve rule metadata. This ensures that the metadata returned is relevant to the given flow.
+
+ Note: At present, only the 'preIssueAccessToken' flow is supported.
+ required: true
+ style: form
+ explode: true
+ schema:
+ type: string
+ enum:
+ - preIssueAccessToken
+ - prePasswordUpdate
+ - preProfileUpdate
+ - preLogin
+ - postLogin
+ - inLogin
+ - preRegistration
+ - inRegistration
+ - inPasswordExpiry
+ responses:
+ "200":
+ description: Applicable fields and operators
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ExpressionMeta'
+ examples:
+ preIssueAccessToken:
+ summary: Sample response for pre-issue access token flow
+ value:
+ - field:
+ name: application
+ displayName: application
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ value:
+ inputType: options
+ valueType: reference
+ valueReferenceAttribute: id
+ valueDisplayAttribute: name
+ links:
+ - href: /applications?offset=0&limit=10
+ method: GET
+ rel: values
+ - href: /applications?filter=name+eq+*&limit=10
+ method: GET
+ rel: filter
+ - field:
+ name: grantType
+ displayName: grant type
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ value:
+ inputType: options
+ valueType: string
+ values:
+ - name: authorization_code
+ displayName: authorization code
+ - name: password
+ displayName: password
+ - name: refresh_token
+ displayName: refresh token
+ - name: client_credentials
+ displayName: client credentials
+ - name: urn:ietf:params:oauth:grant-type:token-exchange
+ displayName: token exchange
+ prePasswordUpdate:
+ summary: Sample response for pre-password update flow
+ value:
+ - field:
+ name: initiator
+ displayName: initiator
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ value:
+ inputType: options
+ valueType: string
+ values:
+ - name: user
+ displayName: user
+ - name: admin
+ displayName: admin
+ - name: application
+ displayName: application
+ - field:
+ name: flow
+ displayName: flow
+ dependentFileds:
+ - initiator
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ value:
+ inputType: options
+ valueType: string
+ values:
+ - name: reset
+ displayName: reset
+ - name: update
+ displayName: update
+ inLogin:
+ summary: Sample response for login flow
+ value:
+ - field:
+ name: role
+ displayName: user.role
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ value:
+ inputType: options
+ valueType: reference
+ valueReferenceAttribute: id
+ valueDisplayAttribute: name
+ links:
+ - href: /scim2/Roles?offset=0&limit=10
+ method: GET
+ rel: values
+ - href: /scim2/Roles?filter=name+eq+*&limit=10
+ method: GET
+ rel: filter
+ - field:
+ name: group
+ displayName: user.group
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ value:
+ inputType: options
+ valueType: reference
+ valueReferenceAttribute: id
+ valueDisplayAttribute: name
+ links:
+ - href: /scim2/Groups?offset=0&limit=10
+ method: GET
+ rel: values
+ - href: /scim2/Groups?filter=name+eq+*&limit=10
+ method: GET
+ rel: filter
+ - field:
+ name: email
+ displayName: user.email
+ operators:
+ - name: equals
+ displayName: equals
+ - name: notEquals
+ displayName: not equals
+ - name: startsWith
+ displayName: starts with
+ - name: endsWith
+ displayName: ends with
+ - name: contains
+ displayName: contains
+ value:
+ inputType: input
+ valueType: string
+ "400":
+ description: Bad Request
+ "401":
+ description: Unauthorized
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ x-codeSamples:
+ - lang: Curl
+ source: |
+ curl --location 'https://api.asgardeo.io/t/{organization-name}/api/server/v1/rules/metadata?flow=preIssueAccessToken' \
+ --header 'Authorization: Bearer {bearer_token}'
+components:
+ schemas:
+ ExpressionMeta:
+ type: array
+ description: Represents the metadata for rule expressions. It includes field definitions and associated operators.
+ items:
+ $ref: '#/components/schemas/FieldDefinition'
+ FieldDefinition:
+ type: object
+ properties:
+ field:
+ $ref: '#/components/schemas/Field'
+ operators:
+ type: array
+ description: |
+ Specifies the list of valid operators that can be applied to this field in rule expressions. Each operator defines a comparison or matching condition (e.g., \"equals\", \"contains\", \"greaterThan\") that determines how the field's value will be evaluated within a rule.
+ items:
+ $ref: '#/components/schemas/Operator'
+ value:
+ $ref: '#/components/schemas/Value'
+ Field:
+ type: object
+ properties:
+ name:
+ type: string
+ description: Name of the field. This is an immutable attribute and uniquely identifies the field allowed in the rule.
+ example: role
+ displayName:
+ type: string
+ description: Display name of the field. Use as a user friendly label of the field to show in UI.
+ example: user.role
+ dependantFields:
+ type: array
+ description: Lists the names of fields on which this field depends for its display or selection in the next expression.
+ example: []
+ items:
+ type: string
+ Value:
+ type: object
+ properties:
+ inputType:
+ type: string
+ description: |
+ Defines how the field should be presented and populated in the rule configuration UI. This property indicates whether the field allows direct user input or if the values are selected from predefined options. Possible types include:
+
+ - "input": Allows for direct user entry, such as text or numeric input.
+ - "options": Provides a list of selectable values, often fetched from an external data source, enabling users to pick from predefined choices.
+ enum:
+ - input
+ - options
+ valueType:
+ type: string
+ description: |
+ Specifies the expected data type for the field’s value within a rule expression. This property defines how the field's value should be interpreted when used in rule conditions. Possible types include:
+ - "string": Text value.
+ - "number": Numerical value.
+ - "boolean": True or false.
+ - "date": Date value.
+ - "reference": A reference to an external identifier, often used with options-type fields to indicate that the value is an ID or a unique attribute from related data."
+ enum:
+ - string
+ - number
+ - boolean
+ - date
+ - reference
+ valueReferenceAttribute:
+ type: string
+ description: "The key attribute in the options data (e.g., 'id') used to represent the option's selected value in rule expressions. Only available when 'valueType' is 'reference'."
+ example: id
+ valueDisplayAttribute:
+ type: string
+ description: "The attribute to show as the label for each option in the dropdown (e.g., 'name') when listing options. Only available when 'valueType' is 'reference'."
+ example: name
+ links:
+ type: array
+ description: Endpoints to retrieve or search for options dynamically. Included only when 'valueType' is 'reference'.
+ example:
+ - href: /scim2/roles?offset=0&limit=10
+ method: GET
+ rel: values
+ - href: /scim2/roles/.search
+ method: GET
+ rel: filter
+ items:
+ $ref: '#/components/schemas/Link'
+ values:
+ type: array
+ description: "List of selectable values for options fields when 'valueType' is 'string', 'number', 'boolean', or 'date'."
+ items:
+ $ref: '#/components/schemas/ValueObject'
+ Operator:
+ type: object
+ properties:
+ name:
+ type: string
+ description: Name of the operator. The immutable identifier of the operator referenced within the rule expression.
+ displayName:
+ type: string
+ description: Display name of the operator. Use as a user friendly label of the operator to show in UI.
+ ValueObject:
+ type: object
+ properties:
+ name:
+ type: string
+ description: The name that uniquely identifies the option.
+ displayName:
+ type: string
+ description: The display name for the option.
+ Link:
+ type: object
+ properties:
+ href:
+ type: string
+ description: Url of the endpoint.
+ method:
+ type: string
+ description: Http method.
+ enum:
+ - GET
+ rel:
+ type: string
+ description: Indicates the endpoint’s relation to retrieving or filtering field values.
+ enum:
+ - values
+ - filter
+ Error:
+ type: object
+ properties:
+ code:
+ type: string
+ description: Error code
+ example: RMS-00000
+ message:
+ type: string
+ description: Error message.
+ example: Some error message.
+ description:
+ type: string
+ description: Detailed error description.
+ example: Some error description.
+ traceId:
+ type: string
+ description: Trace identifier to refer at troubleshooting logs to troubleshoot the problem.
+ example: e0fbcfeb-3617-43c4-8dd0-7b7d38e13047
+ securitySchemes:
+ OAuth2:
+ type: oauth2
+ flows:
+ authorizationCode:
+ authorizationUrl: 'https://api.asgardeo.io/t/{org-name}/oauth2/authorize'
+ tokenUrl: 'https://api.asgardeo.io/t/{org-name}/oauth2/token'
+ scopes:
+ read: internal_rule_metadata_view
diff --git a/en/asgardeo/docs/apis/rule-metadata-rest-api.md b/en/asgardeo/docs/apis/rule-metadata-rest-api.md
new file mode 100644
index 0000000000..3ead0563dd
--- /dev/null
+++ b/en/asgardeo/docs/apis/rule-metadata-rest-api.md
@@ -0,0 +1,5 @@
+---
+template: templates/redoc.html
+---
+
+
\ No newline at end of file
diff --git a/en/asgardeo/docs/complete-guides/angular/accessing-protected-api.md b/en/asgardeo/docs/complete-guides/angular/accessing-protected-api.md
new file mode 100644
index 0000000000..0efd4cbb2d
--- /dev/null
+++ b/en/asgardeo/docs/complete-guides/angular/accessing-protected-api.md
@@ -0,0 +1,109 @@
+---
+template: templates/complete-guide.html
+heading: Accessing protected API from your Angular app
+read_time: 2 min
+---
+
+We’ve covered most of the key activities for adding user login to your Angular app. To recap, during user login, the Angular OAuth2 OIDC SDK provides both an ID token and an access token. We’ve been using the ID token in the previous sections to establish the logged-in user context and enable secure access. In this section, we’ll focus on how to call a secure API from your Angular app using the other token—the access token.
+
+For simplicity, let's assume that the APIs we’re calling are secured by the same Identity Provider (IdP) and use the same issuer— in this case, the same Asgardeo organization. This is typical when Angular apps are interacting with internal APIs within the same organization. However, if your app needs to call APIs secured by a different IdP, you’ll need to exchange your current access token for a new one issued by the IdP securing those APIs. This can be done using the OAuth2 token exchange grant type or other supported grant types. We will cover these scenarios in a separate guide.
+
+## Using SDK Built-in HTTP client
+
+You can utilize Angular's `HttpClient` to make HTTP requests to secure endpoints. You don't need to manually attach the access token to requests if you use the Angular OAuth2 OIDC SDK correctly, as it will handle that automatically.
+The following is a simple example of how you might use the Angular OAuth2 OIDC SDK’s `HttpClient` to call a protected API endpoint, such as `/scim2/me` (to get the user profile details after signing in). In this case, the SCIM 2 endpoint is secured by the same Asgardeo organization. Asgardeo provides a SCIM 2 API for managing users within your organization. While user management with SCIM 2 is a topic for a different guide, we will use the API as part of our current guide.
+
+### Step 1: Import Required Modules
+
+Update the `app.config.ts` file as follows to configure the allowed URLs and include the access token in API requests. Ensure you refer to the domains of your API server under `allowedUrls` and set `sendAccessToken` to `true` so that the access token is included in the requests made to these endpoints:
+
+
+```javascript title="src/main.jsx" hl_lines="5-11"
+import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
+
+export const appConfig: ApplicationConfig = {
+ providers: [provideRouter(routes),
+ provideHttpClient(withInterceptorsFromDi()),
+ provideOAuthClient({
+ resourceServer: {
+ allowedUrls: ['https://api.asgardeo.io'],
+ sendAccessToken: true
+ }
+ }),
+ {
+ provide: APP_INITIALIZER,
+ useFactory: initializeOAuth,
+ deps: [OAuthService],
+ multi: true
+ }
+ ]
+};
+
+```
+
+
+### Step 2: Make HTTP Requests
+
+In your component, you can use Angular's `HttpClient` to call secure APIs. Here's how to do it:
+
+```javascript title="src/main.jsx" hl_lines="16"
+
+import { Component, inject } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+
+@Component({
+ selector: 'app-dashboard',
+ standalone: true,
+ imports: [],
+ templateUrl: './dashboard.component.html',
+ styleUrl: './dashboard.component.css'
+})
+export class DashboardComponent {
+ private http = inject(HttpClient);
+ data: any;
+
+ constructor() {
+ this.http.get('https://api.asgardeo.io/t/mifrazmurthaja/scim2/Me')
+ .subscribe(response => this.data = response);
+ }
+}
+
+
+```
+
+In the above code, the access token is automatically attached to the `Authorization` header by the Angular OAuth2 OIDC SDK when you make requests to the specified allowed URLs.
+
+
+## Manually Managing Access Tokens in API Requests
+
+If you are not using the built-in access token management, you can manually fetch the access token and attach it to your requests. Here’s how to do that:
+
+
+```javascript title="src/main.jsx"
+
+import { Component, inject } from '@angular/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { OAuthService } from 'angular-oauth2-oidc';
+
+@Component({
+ selector: 'app-dashboard',
+ standalone: true,
+ imports: [],
+ templateUrl: './dashboard.component.html',
+ styleUrl: './dashboard.component.css'
+})
+export class DashboardComponent {
+ private http = inject(HttpClient);
+ data: any;
+
+ constructor(private oAuthService : OAuthService) {
+ const token = this.oAuthService.getAccessToken();
+ const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);
+ this.http.get('https://api.asgardeo.io/t/mifrazmurthaja/scim2/Me', { headers })
+ .subscribe(response => this.data = response);
+ }
+}
+
+
+
+```
\ No newline at end of file
diff --git a/en/asgardeo/docs/complete-guides/angular/add-login-and-logout.md b/en/asgardeo/docs/complete-guides/angular/add-login-and-logout.md
new file mode 100644
index 0000000000..af3aefebfc
--- /dev/null
+++ b/en/asgardeo/docs/complete-guides/angular/add-login-and-logout.md
@@ -0,0 +1,99 @@
+---
+template: templates/complete-guide.html
+heading: Add login and logout to your app
+read_time: 2 min
+---
+
+Next, let's add login and logout features to your Angular app. Angular uses services to access authentication data, and we can inject the `OAuthService` into your components to manage user authentication. The `OAuthService` provides methods for logging in and out, checking the user's authentication status, and retrieving access tokens. The key methods you will use are `initLoginFlow()` for signing in and `revokeTokenAndLogout()` for signing out. You can use these methods directly within your Angular components to trigger login and logout actions.
+
+Replace the existing content of the `app.component.ts` file with following content.
+
+!!! tip
+ For better organization, you can create separate components for different purposes, such as login and home pages. However, for simplicity, we are using the default component in this example.
+
+```javascript title="app.component.ts" hl_lines="16-28"
+
+import { Component } from '@angular/core';
+import { RouterOutlet } from '@angular/router';
+import { OAuthService } from 'angular-oauth2-oidc';
+import { CommonModule } from '@angular/common';
+
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [RouterOutlet, CommonModule],
+ templateUrl: './app.component.html',
+ styleUrl: './app.component.css'
+})
+
+export class AppComponent {
+ title = 'asgardeo-angular';
+ isAuthorized = this.oAuthService.hasValidAccessToken();
+
+ constructor(private oAuthService: OAuthService) {
+
+ }
+
+ login() {
+ this.oAuthService.initLoginFlow();
+ }
+
+ logout() {
+ this.oAuthService.revokeTokenAndLogout();
+ }
+}
+
+```
+
+Once you've defined these methods in app.component.ts, update the corresponding HTML template in app.component.html by modifying the lines below:
+
+```html title="app.component.html"
+
+
+
+
+
+```
+
+Let’s look into the underlying details of what’s happening here.
+
+The `AppComponent` leverages the `OAuthService`, which was initialized earlier in the `ApplicationConfig` using `authConfig`, to access various methods and attributes provided by the SDK, such as `initLoginFlow()`, `revokeTokenAndLogout()`, and user-specific attributes. The `AppComponent` defines its own methods, like `login()` and `logout()`, which make use of these SDK methods.
+
+In `app.component.html`, these methods are tied to button click events. The template also dynamically renders content based on the user's authentication status. It checks for the presence of the username attribute in the session to determine if the user is authenticated. If username is available, indicating that the user is logged in, the "Logout" button is displayed and triggers the `logout()` method. Otherwise, the "Login" button is shown, which initiates the login process via `login()`.
+
+Save the changes and re-run the application.
+
+```bash
+ng serve
+
+```
+
+Visit your app's homepage at [http://localhost:4200](http://localhost:4200).
+
+
+## Initiate Sign In
+Clicking on the login button will initiate an OIDC request. You can observe this authorization request in the browser's DevTools. To do so, right-click on the application, click "Inspect," switch to the "Network" tab, and in the filter input, type "authorize." Then, click on the Login button to see the details of the request.
+
+![OIDC request]({{base_path}}/complete-guides/angular/assets/img/image15.png){: width="800" style="display: block; margin: 0;"}
+
+!!! tip "Tip"
+
+ The OpenID Connect specification offers several functions, known as grant types, to obtain an access token in exchange for user credentials. This example uses the authorization code grant type. In this process, the app first requests a unique code from the authentication server, which can later be used to obtain an access token. For more details on the authorization code grant type, please refer to the [Asgardeo documentation.](https://wso2.com/asgardeo/docs/guides/authentication/oidc/implement-auth-code-with-pkce/){:target="_blank"}
+
+Asgardeo will receive this authorization request and respond by redirecting the user to a login page to enter their credentials.
+
+![OIDC request]({{base_path}}/complete-guides/angular/assets/img/image16.png){: width="800" style="display: block; margin: 0;"}
+
+At this stage, **you need to create a [test user in Asgardeo](https://wso2.com/asgardeo/docs/guides/users/manage-users/#onboard-users){:target="_blank"} to try out the application.** Once you create a test user, you can enter the username and password of the test user to the login screen.
+
+!!! tip "Tip"
+
+ **PKCE (Proof Key for Code Exchange)** is an addition to the OAuth2 specification to make the authorization code more immune to replay attacks. It is enabled by default for public clients such as our single page Angular app.
+
+ If you want to disable PKCE for some reason, you can do so via following the steps below. **However, disabling PKCE for public clients such as our single page Angular app is highly discouraged.**
+
+ 1. Log in to the {{product_name}} console and select the application you created.
+ 2. Switch to the Protocol tab.
+ 3. Uncheck the Mandatory checkbox under PKCE section.
+
+In this section, we have added login and logout features to our Angular app. In the next step, we will look into how to access the user attributes of the logged in user.
diff --git a/en/asgardeo/docs/complete-guides/angular/assets/img/image15.png b/en/asgardeo/docs/complete-guides/angular/assets/img/image15.png
new file mode 100644
index 0000000000..1b44db387c
Binary files /dev/null and b/en/asgardeo/docs/complete-guides/angular/assets/img/image15.png differ
diff --git a/en/asgardeo/docs/complete-guides/angular/assets/img/image16.png b/en/asgardeo/docs/complete-guides/angular/assets/img/image16.png
new file mode 100644
index 0000000000..3c01602b1b
Binary files /dev/null and b/en/asgardeo/docs/complete-guides/angular/assets/img/image16.png differ
diff --git a/en/asgardeo/docs/complete-guides/angular/assets/img/image5.png b/en/asgardeo/docs/complete-guides/angular/assets/img/image5.png
new file mode 100644
index 0000000000..5fd6c72c07
Binary files /dev/null and b/en/asgardeo/docs/complete-guides/angular/assets/img/image5.png differ
diff --git a/en/asgardeo/docs/complete-guides/angular/assets/img/image6.png b/en/asgardeo/docs/complete-guides/angular/assets/img/image6.png
new file mode 100644
index 0000000000..eea3f0c296
Binary files /dev/null and b/en/asgardeo/docs/complete-guides/angular/assets/img/image6.png differ
diff --git a/en/asgardeo/docs/complete-guides/angular/assets/img/image8.png b/en/asgardeo/docs/complete-guides/angular/assets/img/image8.png
new file mode 100644
index 0000000000..e10051c0ad
Binary files /dev/null and b/en/asgardeo/docs/complete-guides/angular/assets/img/image8.png differ
diff --git a/en/asgardeo/docs/complete-guides/angular/create-app.md b/en/asgardeo/docs/complete-guides/angular/create-app.md
new file mode 100644
index 0000000000..f684ec3eb9
--- /dev/null
+++ b/en/asgardeo/docs/complete-guides/angular/create-app.md
@@ -0,0 +1,45 @@
+---
+template: templates/complete-guide.html
+heading: Create an Angular app
+read_time: 2 min
+---
+
+For this guide, you will be creating a simple Angular app using Angular CLI, the official tool provided by Angular to simplify project scaffolding and development.
+
+!!! note
+
+ The Angular OAuth2 OIDC SDK supports only up to Angular CLI version 17. Therefore, we are creating this application using Angular CLI version 17.
+
+
+Open a terminal, change the directory to where you want to initialize the project, and run the following command to create your first Angular sample application
+
+
+```bash
+npm install -g @angular/cli@17
+
+ng new asgardeo-angular
+```
+
+Running this command will create a folder with a ready-made Angular application.
+
+Once the application is created, install the necessary dependencies using the following command:
+
+
+```bash
+
+cd asgardeo-angular
+
+npm install
+```
+
+Then run the sample in the development mode. This allows you to see real-time updates and debug the app as you make changes.
+
+```bash
+ng serve
+```
+
+By default, the development server will run on the port 4200. You can navigate to [http://localhost:4200](http://localhost:4200){:target="_blank"} in your browser, and you should see the sample application working as expected.
+
+![Navigate to localhost]({{base_path}}/complete-guides/angular/assets/img/image6.png){: width="600" style="display: block; margin: 0;"}
+
+At this point, you have a simple yet fully functional Angular app. In the next step, let’s try to integrate an authentication SDK with the app.
diff --git a/en/asgardeo/docs/complete-guides/angular/display-logged-in-user-details.md b/en/asgardeo/docs/complete-guides/angular/display-logged-in-user-details.md
new file mode 100644
index 0000000000..3da0d9b031
--- /dev/null
+++ b/en/asgardeo/docs/complete-guides/angular/display-logged-in-user-details.md
@@ -0,0 +1,76 @@
+---
+template: templates/complete-guide.html
+heading: Display logged-in user details
+read_time: 2 min
+---
+
+At this point, we’ve successfully implemented login and logout capabilities by integrating your Angular app with {{product_name}}. The next step is to access and display the logged-in user details within the application. The SDK provides a way to retrieve the authenticated user’s basic information.
+
+To do this, you can leverage the `getIdentityClaims` method to fetch the user’s profile information. The following code example demonstrates how to access and display the user's profile information in your Angular component.
+
+Add the `username()` function to the `app.component.ts` file to access the username attribute.
+
+```javascript title="app.component.ts"
+
+
+ get username() {
+ var claims = this.oAuthService.getIdentityClaims();
+ if (!claims) return null;
+ return claims['username'];
+ }
+
+
+```
+
+
+Next, modify the `app.component.html` file with the following code.
+
+```html title="app.component.html" hl_lines="2"
+
+
+
Hello {{ username }}!
+
+
+```
+
+
+## Getting additional user attributes
+
+In the above code, we have rendered only the username of the logged-in user. Similarly, you can access other user attributes, such as given_name and and country. The following code snippet illustrates how to access these attributes in your app. The Angular OAuth2 OIDC SDK is responsible for processing the ID token and decoding these attributes.
+
+1. Log in to the {{product_name}} console and select the application you created.
+2. Go to the **User Attributes** tab.
+3. Select the **given_name** attribute.
+4. Click Update to save the changes.
+
+Add the `username()` function to the `app.component.ts` file to access the username attribute.
+
+```javascript title="app.component.ts" hl_lines="7-11"
+ get username() {
+ var claims = this.oAuthService.getIdentityClaims();
+ if (!claims) return null;
+ return claims['username'];
+ }
+
+ get givenName() {
+ var claims = this.oAuthService.getIdentityClaims();
+ if (!claims) return null;
+ return claims['given_name'];
+ }
+
+```
+
+
+Now, we can display the given_name attribute by modify the `app.component.html` file with the following code.
+
+```html title="app.component.html" hl_lines="3"
+
+
+