Skip to content
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
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
node-version: [ 20.x, 22.x ]
env:
FIREBASE_TEST_USER: ${{ secrets.FIREBASE_TEST_USER }}
FIREBASE_TEST_USER_LOCAL: ${{ secrets.FIREBASE_TEST_USER_LOCAL }}
FIREBASE_SERVICE_ACCOUNT_BASE64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BASE64 }}
FIREBASE_CLIENT_BASE64: ${{ secrets.FIREBASE_CLIENT_BASE64 }}

Expand Down
47 changes: 13 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { FirebaseAuthGuard } from '@alpha018/nestjs-firebase-auth';
checkRevoked: true, // Set to true if you want to check for revoked Firebase tokens
validateRole: true, // Set to true if you want to validate user roles
useLocalRoles: true, // Set to true if you want to validate user roles locally without firebase call
rolesClaimKey: 'user_roles' // Set the name of the key within the Firebase custom claims that stores user roles
},
},
}),
Expand All @@ -74,6 +75,7 @@ import { FirebaseAuthGuard } from '@alpha018/nestjs-firebase-auth';
| `auth.config.checkRevoked` | `boolean` | Optional | Set to `true` to check if the Firebase token has been revoked. Defaults to `false`. |
| `auth.config.validateRole` | `boolean` | Optional | Set to `true` to validate user roles using Firebase custom claims. Defaults to `false`. |
| `auth.config.useLocalRoles` | `boolean` | Optional | Set to `true` to validate user roles using local custom claims inside the JWT token. Defaults to `false`. **Note:** If you update the claims, previously issued tokens may still contain outdated roles and remain valid. |
| `auth.config.rolesClaimKey` | `string` | Optional | The name of the key within the Firebase custom claims that stores user roles. Defaults to `'roles'`. This allows you to customize the property name for roles in your custom claims object. |


### Auth Guard Without Role Validation
Expand All @@ -96,7 +98,7 @@ export class AppController {

### Auth Guard With Role Validation

To enforce role-based access control, you need to set custom claims in Firebase. Here's how you can set custom claims:
To enforce role-based access control, you need to set role-based custom claims in Firebase. Here's how you can set roles for a user using `setClaimsRoleBase`:
```ts
import { FirebaseProvider } from '@alpha018/nestjs-firebase-auth';

Expand All @@ -106,16 +108,16 @@ enum Roles {
}

@Controller('')
export class AppController implements OnModuleInit {
export class AppController {
constructor(
private readonly firebaseProvider: FirebaseProvider,
) {}

@Get()
async setClaims() {
async setUserRoles() {
await this.firebaseProvider.setClaimsRoleBase<Roles>(
'FirebaseUID',
[Roles.ADMIN, ...]
'some-firebase-uid', // The UID of the user you want to set roles for
[Roles.ADMIN]
);
return { status: 'ok' }
}
Expand Down Expand Up @@ -147,36 +149,13 @@ export class AppController {

### Additional Information

To retrieve user claims, use the following example:
```ts
import { FirebaseProvider } from '@alpha018/nestjs-firebase-auth';

enum Roles {
ADMIN,
USER,
}

@Controller('')
export class AppController {
constructor(
private readonly firebaseProvider: FirebaseProvider,
) {}

@Get()
async mainFunction() {
const claims = await this.firebaseProvider.getClaimsRoleBase<Roles>(
'FirebaseUID',
);
return claims; // This returns an array of the user's claims
}
}
```

To retrieve Decode ID Token and Claims, use the following example:
To retrieve the Decoded ID Token and role claims within a protected route, use the `@FirebaseUser` and `@FirebaseRolesClaims` parameter decorators.
```ts
import {
FirebaseGuard,
FirebaseProvider, FirebaseUser, FirebaseUserClaims,
FirebaseProvider,
FirebaseUser,
FirebaseRolesClaims,
RolesGuard,
} from '@alpha018/nestjs-firebase-auth';

Expand All @@ -198,7 +177,7 @@ export class AppController {
@Get()
async mainFunction(
@FirebaseUser() user: auth.DecodedIdToken,
@FirebaseUserClaims() claims: Roles[],
@FirebaseRolesClaims() claims: Roles[],
) {
return {
user,
Expand All @@ -213,7 +192,7 @@ export class AppController {
> **Note:** Starting from version `>=1.7.x`, these two decorators are explicitly separated to avoid confusion (see [issue #11](https://github.com/Alpha018/nestjs-firebase-auth/issues/11)):

- `@FirebaseUser()` → Returns the **full decoded token** (`auth.DecodedIdToken`).
- `@FirebaseUserClaims()` → Returns only the **custom claims** (roles/permissions) defined for the user.
- `@FirebaseUserClaims()` → Returns only the **custom role claims** (roles/permissions) defined for the user.

This separation ensures that developers can access both the raw Firebase user object and the role/claims information independently.

Expand Down
120 changes: 59 additions & 61 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"postinstall": "husky || true"
"prepare": "husky || exit 0"
},
"dependencies": {
"@nestjs/common": "^11.1.5",
Expand Down
3 changes: 3 additions & 0 deletions src/firebase/constant/firebase.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ export const FIREBASE_TOKEN_USER_METADATA = 'FIREBASE_USER_METADATA';
export const FIREBASE_CLAIMS_USER_METADATA = 'FIREBASE_CLAIMS_METADATA';
/** Metadata key for role based authorization decorator */
export const FIREBASE_APP_ROLES_DECORATOR = 'ROLES';

export const FIREBASE_APP_ROLES_DEFAULT_DECORATOR = 'roles';
export const FIREBASE_AUTH_OPTIONS = 'FIREBASE_AUTH_OPTIONS';
12 changes: 12 additions & 0 deletions src/firebase/decorator/claims.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,19 @@ export const ClaimsFactory = (data: unknown, ctx: ExecutionContext) => {
return request.metadata?.[FIREBASE_CLAIMS_USER_METADATA as string]?.claims;
};

/**
* Parameter decorator to access a user's role-based Firebase claims.
*
* This decorator extracts the role claims attached to the request by the `FirebaseGuard`.
* The specific claims returned depend on the `rolesClaimKey` configuration.
*/
export const FirebaseRolesClaims = createParamDecorator(ClaimsFactory);

/**
* Parameter decorator to access a user’s Firebase claims.
*
* @deprecated Use `@FirebaseRolesClaims()` instead for better clarity.
* This decorator is kept for backward compatibility and functions identically
* to `@FirebaseRolesClaims`.
*/
export const FirebaseUserClaims = createParamDecorator(ClaimsFactory);
Loading