Skip to content

Commit

Permalink
fix: setup-project fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dereekb committed May 26, 2022
1 parent 45821ae commit d700370
Show file tree
Hide file tree
Showing 14 changed files with 178 additions and 97 deletions.
29 changes: 21 additions & 8 deletions apps/demo-api/src/app/common/firebase/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { CallableContextWithAuthData, AbstractFirebaseServerAuthContext, AbstractFirebaseServerAuthService, AbstractFirebaseServerAuthUserContext } from "@dereekb/firebase-server";
import { AuthClaims, AuthRoleSet } from "@dereekb/util";
import { AuthClaims, AuthClaimsUpdate, AuthRoleSet, AUTH_ADMIN_ROLE, AuthRoleClaimsFactoryConfig, authRoleClaimsService } from "@dereekb/util";

export type DemoApiAuthClaims = {

/**
* Admin role
*/
a?: number;

}

export class DemoApiFirebaseServerAuthUserContext extends AbstractFirebaseServerAuthUserContext<DemoApiAuthService> {

Expand All @@ -11,6 +20,14 @@ export class DemoApiFirebaseServerAuthContext extends AbstractFirebaseServerAuth

export class DemoApiAuthService extends AbstractFirebaseServerAuthService<DemoApiFirebaseServerAuthUserContext, DemoApiFirebaseServerAuthContext> {

static readonly DEMO_API_CLAIMS_CONFIG: AuthRoleClaimsFactoryConfig<DemoApiAuthClaims> = {
a: {
roles: AUTH_ADMIN_ROLE
}
};

static readonly DEMO_API_CLAIMS_SERVICE = authRoleClaimsService(DemoApiAuthService.DEMO_API_CLAIMS_CONFIG);

protected _context(context: CallableContextWithAuthData): DemoApiFirebaseServerAuthContext {
return new DemoApiFirebaseServerAuthContext(this, context);
}
Expand All @@ -20,15 +37,11 @@ export class DemoApiAuthService extends AbstractFirebaseServerAuthService<DemoAp
}

readRoles(claims: AuthClaims): AuthRoleSet {
const roles = new Set<string>();

return roles;
return DemoApiAuthService.DEMO_API_CLAIMS_SERVICE.toRoles(claims);
}

claimsForRoles(roles: AuthRoleSet): AuthClaims {
const claims: AuthClaims = {};

return claims;
claimsForRoles(roles: AuthRoleSet): AuthClaimsUpdate {
return DemoApiAuthService.DEMO_API_CLAIMS_SERVICE.toClaims(roles);
}

}
1 change: 0 additions & 1 deletion components/demo-firebase/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module.exports = {
displayName: 'demo-firebase',

globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ services:
tty: true
networks:
- demo-api-network

networks:
demo-api-network:
driver: bridge
29 changes: 10 additions & 19 deletions packages/firebase-server/src/lib/auth/auth.nest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ const firebaseAdminFunctionNestContext = firebaseAdminFunctionNestContextFactory

const userContext = authorizedUserContextFactory({});

type LoadClaimsTest = {
test?: number;
second?: number;
}

describe('firebase server auth', () => {

initFirebaseServerAdminTestEnvironment();
Expand Down Expand Up @@ -135,13 +140,13 @@ describe('firebase server auth', () => {
test: 1
};

let claims = await authUserContext.loadClaims<typeof data>();
let claims = await authUserContext.loadClaims<LoadClaimsTest>();
expect(claims).toBeDefined();
expect(objectHasNoKeys(claims)).toBe(true);

await authUserContext.setClaims(data);

claims = await authUserContext.loadClaims<typeof data>();
claims = await authUserContext.loadClaims<LoadClaimsTest>();
expect(claims).toBeDefined();
expect(claims.test).toBe(1);
});
Expand All @@ -151,16 +156,11 @@ describe('firebase server auth', () => {
describe('updateClaims()', () => {

it('should update the existing claims.', async () => {
const data = {
test: 1,
second: null
};

await authUserContext.setClaims({
test: 1
});

let claims = await authUserContext.loadClaims<typeof data>();
let claims = await authUserContext.loadClaims<LoadClaimsTest>();
expect(claims).toBeDefined();
expect(claims!.test).toBe(1);
expect(claims!.second).not.toBe(2);
Expand All @@ -176,17 +176,12 @@ describe('firebase server auth', () => {
});

it('should remove any keys with null update values', async () => {
const data = {
test: 1,
second: null
};

await authUserContext.setClaims({
test: 1,
second: 2
});

let claims = await authUserContext.loadClaims<typeof data>();
let claims = await authUserContext.loadClaims<LoadClaimsTest>();
expect(claims).toBeDefined();
expect(claims!.test).toBe(1);

Expand All @@ -205,15 +200,11 @@ describe('firebase server auth', () => {
describe('clearClaims()', () => {

it('should clear the claims.', async () => {
const data = {
test: 1
};

await authUserContext.setClaims({
test: 1
});

let claims = await authUserContext.loadClaims<typeof data>();
let claims = await authUserContext.loadClaims<LoadClaimsTest>();
expect(claims).toBeDefined();
expect(claims!.test).toBe(1);

Expand Down
12 changes: 6 additions & 6 deletions packages/firebase-server/src/lib/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { FirebaseAuthUserId } from '@dereekb/firebase';
import { filterUndefinedValues, AUTH_ADMIN_ROLE, AuthClaims, AuthRoleSet, cachedGetter, filterNullAndUndefinedValues, ArrayOrValue, AuthRole, forEachKeyValue, ObjectMap, AuthClaimsUpdate, asSet, KeyValueTypleValueFilter } from '@dereekb/util';
import { filterUndefinedValues, AUTH_ADMIN_ROLE, AuthClaims, AuthRoleSet, cachedGetter, filterNullAndUndefinedValues, ArrayOrValue, AuthRole, forEachKeyValue, ObjectMap, AuthClaimsUpdate, asSet, KeyValueTypleValueFilter, AuthClaimsObject } from '@dereekb/util';
import { assertIsContextWithAuthData, CallableContextWithAuthData } from '../function/context';

export interface FirebaseServerAuthUserIdentifierContext {
Expand Down Expand Up @@ -42,7 +42,7 @@ export interface FirebaseServerAuthUserContext extends FirebaseServerAuthUserIde
/**
* Loads the claims from the user.
*/
loadClaims<T = unknown>(): Promise<AuthClaims<T>>;
loadClaims<T extends AuthClaimsObject = AuthClaimsObject>(): Promise<AuthClaims<T>>;

/**
* Updates the claims for a user by merging existing claims in with the input.
Expand Down Expand Up @@ -108,7 +108,7 @@ export abstract class AbstractFirebaseServerAuthUserContext<S extends FirebaseSe
return filterNullAndUndefinedValues(this.service.claimsForRoles(asSet(roles)));
}

loadClaims<T = unknown>(): Promise<AuthClaims<T>> {
loadClaims<T extends AuthClaimsObject = AuthClaimsObject>(): Promise<AuthClaims<T>> {
return this.loadRecord().then(x => (x.customClaims ?? {}) as AuthClaims<T>);
}

Expand Down Expand Up @@ -180,8 +180,8 @@ export interface FirebaseServerAuthContext<U extends FirebaseServerAuthUserConte

export abstract class AbstractFirebaseServerAuthContext<C extends FirebaseServerAuthContext, U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext, S extends FirebaseServerAuthService<U, C> = FirebaseServerAuthService<U, C>> implements FirebaseServerAuthContext {

private readonly _isAdmin = cachedGetter(() => this.service.isAdmin(this.context.auth.token));
private readonly _authRoles = cachedGetter(() => this.service.readRoles(this.context.auth.token));
private readonly _isAdmin = cachedGetter(() => this.service.isAdmin(this.claims));
private readonly _authRoles = cachedGetter(() => this.service.readRoles(this.claims));
private readonly _userContext = cachedGetter(() => this.service.userContext(this.context.auth.uid));

constructor(readonly service: S, readonly context: CallableContextWithAuthData) { }
Expand All @@ -203,7 +203,7 @@ export abstract class AbstractFirebaseServerAuthContext<C extends FirebaseServer
}

get claims(): AuthClaims {
return this.context.auth.token;
return this.context.auth.token as unknown as AuthClaims;
}

// MARK: FirebaseServerAuthUserContext
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { snapshotConverterFunctions } from './snapshot';
import { firestoreBoolean, firestoreString } from './snapshot.field';

describe('makeSnapshotConverterFunctions()', () => {
describe('snapshotConverterFunctions()', () => {

it('should create conversion functions for the input.', () => {
const result = snapshotConverterFunctions({
Expand Down
27 changes: 20 additions & 7 deletions packages/util/src/lib/auth/auth.role.claims.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { AUTH_USER_ROLE } from '@dereekb/util';
import { AUTH_USER_ROLE, Maybe } from '@dereekb/util';
import { containsAllValues, hasDifferentValues } from '../set';
import { AuthRoleSet, AUTH_ADMIN_ROLE } from './auth.role';
import { AuthClaimValue, AuthRoleClaimsService, authRoleClaimsService, AUTH_ROLE_CLAIMS_DEFAULT_CLAIM_VALUE, AUTH_ROLE_CLAIMS_DEFAULT_EMPTY_VALUE } from "./auth.role.claims";
import { AuthClaimsObject, AuthRoleClaimsService, authRoleClaimsService, AUTH_ROLE_CLAIMS_DEFAULT_CLAIM_VALUE, AUTH_ROLE_CLAIMS_DEFAULT_EMPTY_VALUE } from "./auth.role.claims";


type TestClaims = {
test: string;
u: number;
m: string;
}

type TestComplexClaims = {
type: number;
}

describe('authRoleClaimsFactory()', () => {

describe('function', () => {

function testConversion(service: AuthRoleClaimsService, rolesSet: AuthRoleSet, name?: string) {
function testConversion<T extends AuthClaimsObject>(service: AuthRoleClaimsService<T>, rolesSet: AuthRoleSet, name?: string) {

it(`should convert the the roles ${((name) ? `"${name}"` : '')} to claims claims and back.`, () => {
const claims = service.toClaims(rolesSet);
Expand All @@ -26,7 +37,9 @@ describe('authRoleClaimsFactory()', () => {
const nonExistentClaim = 'x';

const claimsConfig = {
test: { roles: 'n' },
test: {
roles: 'n'
},
u: {
roles: AUTH_USER_ROLE,
value: 10
Expand All @@ -36,7 +49,7 @@ describe('authRoleClaimsFactory()', () => {
}
};

const service = authRoleClaimsService(claimsConfig);
const service = authRoleClaimsService<TestClaims>(claimsConfig);

testConversion(service, new Set([claimsConfig.u.roles, ...claimsConfig.m.roles, claimsConfig.test.roles]));

Expand Down Expand Up @@ -89,7 +102,7 @@ describe('authRoleClaimsFactory()', () => {
return 2;
}
},
decodeRolesFromValue: (value: AuthClaimValue) => {
decodeRolesFromValue: (value: Maybe<number>) => {
switch (value) {
case 1:
return [AUTH_ADMIN_ROLE];
Expand All @@ -100,7 +113,7 @@ describe('authRoleClaimsFactory()', () => {
}
};

const service = authRoleClaimsService(claimsConfig);
const service = authRoleClaimsService<TestComplexClaims>(claimsConfig);

testConversion(service, new Set([AUTH_ADMIN_ROLE]), 'admin');
testConversion(service, new Set([AUTH_USER_ROLE]), 'user');
Expand Down
Loading

0 comments on commit d700370

Please sign in to comment.