Skip to content
Open
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
148 changes: 148 additions & 0 deletions services/authentication-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,36 @@ npm i @sourceloop/authentication-service
- Use `/verify-otp` to enter otp or code from authenticator app.
for using Google Authenticator user needs to pass client id in the payload which is optional in case for OTP

- **Oauth- using Cognito** -
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent capitalization: 'Oauth' should be 'OAuth' to match the naming convention used elsewhere in the document (see line 160).

Suggested change
- **Oauth- using Cognito** -
- **OAuth- using Cognito** -

Copilot uses AI. Check for mistakes.
- Make sure your AWS Cognito setup is properly configured. You can refer to the official documentation [here](https://docs.aws.amazon.com/cognito/latest/developerguide/authentication.html).
- Add the following environment variables:

COGNITO_AUTH_CALLBACK_URL= \
COGNITO_AUTH_CLIENT_DOMAIN=\
COGNITO_AUTH_CLIENT_ID=\
COGNITO_AUTH_CLIENT_SECRET=\
COGNITO_AUTH_REGION=

COGNITO_AUTH_CALLBACK_URL should point to the /auth/cognito-auth-redirect endpoint provided by the authentication service.
- Add NODE_TLS_REJECT_UNAUTHORIZED=0 in environment to disables TLS/SSL certificate validation in Node.js. for ***Development only***.
- We are using the loopback4-authentication package in the backend service. The User, AuthClient, and UserCredential models, along with the /auth/cognito and /auth/cognito-auth-redirect APIs, have been set up in the authentication service. You only need to bind the required providers as described in the [loopback4-authentication](https://github.com/sourcefuse/loopback4-authentication)
- When the application is redirected back with the authorization code generated by the callback API, the application can send this code to the /auth/token endpoint to obtain the access token for your application.
- Create an auth_client entry in your database using the query below:

```typescript
INSERT INTO auth_clients (client_id, client_secret, secret)
VALUES ('temp_client', 'temp_secret', 'secret');
```
Use the client_id and client_secret to invoke the auth/cognito API from the frontend.
- Additionally, configure the redirect_url for this auth client to point to the frontend URL where you want the user to be redirected after successful authorization from Cognito. The user will be redirected to this URL with a code query parameter, which can then be exchanged for a token using the /auth/token endpoint.
- The OAuth endpoints are meant to be accessed from a web browser, not from API testing tools. The API explorer shows you
the endpoint structure, but you must test OAuth flows through:
- Your frontend application
- A real browser session
- Tools specifically designed for OAuth testing (like Postman with proper OAuth 2.0 support)

Kindly create a Dummy web App to hit and manage the apis.

- **OAuth- using Azure AD** -

- Passport strategy for authenticating via Azure Ad using [passport-azure-ad](https://www.npmjs.com/package/passport-azure-ad).
Expand Down Expand Up @@ -528,6 +558,8 @@ sequenceDiagram

Here is a sample Implementation `DataSource` implementation using environment variables and PostgreSQL as the data source. The `auth-multitenant-example` utilizes both Redis and PostgreSQL as data sources.

run - ```npm install loopback-connector-postgresql --save```

```typescript
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
Expand Down Expand Up @@ -562,6 +594,77 @@ export class AuthenticationDbDataSource
}
}
```
redis datasource -
run - ```npm install loopback-connector-kv-redis --save```
```typescript
for redis, datasource example is as below
Comment on lines +597 to +600
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent capitalization: 'redis' should be 'Redis' to match proper noun convention.

Suggested change
redis datasource -
run - ```npm install loopback-connector-kv-redis --save```
```typescript
for redis, datasource example is as below
Redis datasource -
run - ```npm install loopback-connector-kv-redis --save```
```typescript
For Redis, datasource example is as below

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent capitalization and style: Should be formatted as a proper sentence, e.g., 'For Redis, the datasource example is as follows:'

Suggested change
for redis, datasource example is as below
For Redis, the datasource example is as follows:

Copilot uses AI. Check for mistakes.
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {AnyObject, juggler} from '@loopback/repository';
import {readFileSync} from 'fs';
import {AuthCacheSourceName} from '@sourceloop/authentication-service';

const config = {
name: process.env.REDIS_NAME,
connector: 'kv-redis',
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
db: process.env.REDIS_DATABASE,
url: process.env.REDIS_URL,
tls:
+process.env.REDIS_TLS_ENABLED! ||
(process.env.REDIS_TLS_CERT
? {
ca: readFileSync(process.env.REDIS_TLS_CERT),
}
: undefined),
sentinels:
+process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINELS
? JSON.parse(process.env.REDIS_SENTINELS)
: undefined,
sentinelPassword:
+process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINEL_PASSWORD
? process.env.REDIS_SENTINEL_PASSWORD
: undefined,
role:
+process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINEL_ROLE
? process.env.REDIS_SENTINEL_ROLE
: undefined,
};

// Observe application's life cycle to disconnect the datasource when
// application is stopped. This allows the application to be shut down
// gracefully. The `stop()` method is inherited from `juggler.DataSource`.
// Learn more at https://loopback.io/doc/en/lb4/Life-cycle.html
@lifeCycleObserver('datasource')
export class RedisDataSource
extends juggler.DataSource
implements LifeCycleObserver
{
static readonly dataSourceName = AuthCacheSourceName;
static readonly defaultConfig = config;

constructor(
@inject(`datasources.config.${process.env.REDIS_NAME}`, {optional: true})
dsConfig: AnyObject = config,
) {
if (
+process.env.REDIS_HAS_SENTINELS! &&
!!process.env.REDIS_SENTINEL_HOST &&
!!process.env.REDIS_SENTINEL_PORT
) {
dsConfig.sentinels = [
{
host: process.env.REDIS_SENTINEL_HOST,
port: +process.env.REDIS_SENTINEL_PORT,
},
];
}
super(dsConfig);
}
}
```


### Migrations

Expand All @@ -576,6 +679,51 @@ NOTE : For [`@sourceloop/cli`](https://www.npmjs.com/package/@sourceloop/cli?act

![Auth DB Schema](https://user-images.githubusercontent.com/77672713/126612271-3ce065aa-9f87-45d4-bf9a-c5cc8ad21764.jpg)

- You can use below sql to create first user. Kindly update the value of any field if required as per application requirement.

```
-- Set schema
SET search_path TO main, public;
-- Auth Client
INSERT INTO auth_clients (client_id, client_secret, secret)
VALUES ('temp_client', 'temp_secret', 'secret');
-- Tenant
INSERT INTO tenants (name, status, key)
VALUES ('Master Tenant', 1, 't1');
-- Role
INSERT INTO roles (name, permissions, allowed_clients, role_type, tenant_id)
SELECT 'SuperAdmin', '{*}', '{temp_client}', 0, id
FROM tenants
WHERE key = 't1';

-- User
INSERT INTO users (first_name, last_name, username, email, default_tenant_id)
SELECT 'John', 'Doe', '[email protected]', '[email protected]', id
FROM tenants
WHERE key = 't1';

-- Assign User to Tenant with Role
INSERT INTO user_tenants (user_id, tenant_id, status, role_id)
SELECT
(SELECT id FROM users WHERE username = '[email protected]'),
(SELECT id FROM tenants WHERE key = 't1'),
1,
(SELECT id FROM roles WHERE role_type = 0 AND tenant_id = (SELECT id FROM tenants WHERE key = 't1') LIMIT 1);

-- User Credentials (bcrypt hashed password)
INSERT INTO user_credentials (user_id, auth_provider, password)
SELECT id, 'internal', '$2b$12$mNyM260paivMGoA0gThnkuYpBZ5V0yJHausASJtHINpMeUd9BJkwi'
FROM users
WHERE username = '[email protected]';

-- Update User with Auth Client
UPDATE users
SET auth_client_ids = ARRAY[
(SELECT id FROM auth_clients WHERE client_id = 'temp_client')::integer
]
WHERE username = '[email protected]';
```
descrypted password is test123!@#, we stored it after encryption.
### Providers

You can find documentation for some of the providers available in this service [here](./src/providers/README.md)
Expand Down
Loading