Skip to content

Commit

Permalink
Merge pull request #112 from o2Labs/2.0.0-release
Browse files Browse the repository at this point in the history
2.0.0 release
  • Loading branch information
Daniel Bradley authored Sep 14, 2020
2 parents f3b5a2b + 1b501b9 commit 6def234
Show file tree
Hide file tree
Showing 18 changed files with 46 additions and 405 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.0.0] - 2020-09-14

- Re-enable API write access.
- Use newly migrated DB (using officeId).
- Require officeId to be specified in config (to avoid renaming issues).
- Disable public Cognito registrations.

## [1.2.0] - 2020-09-14

- Migrate DB to store all bookings with office ID rather than office name.
Expand Down
8 changes: 3 additions & 5 deletions infrastructure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,9 @@ const userPool = new aws.cognito.UserPool(`${serviceName}-users`, {
preSignUp: preSignUp.arn,
verifyAuthChallengeResponse: verifyAuthChallengeResponse.arn,
},
// TODO: Block public sign-ups to the user pool.
// adminCreateUserConfig: {
// allowAdminCreateUserOnly: true,
// },
adminCreateUserConfig: {
allowAdminCreateUserOnly: true,
},
tags,
});

Expand Down Expand Up @@ -414,7 +413,6 @@ const getHttpEnv = (): aws.types.input.lambda.FunctionEnvironment['variables'] =
DEFAULT_WEEKLY_QUOTA: defaultWeeklyQuota.toString(),
DATA_RETENTION_DAYS: logRetention.toString(),
SHOW_TEST_BANNER: showTestBanner.toString(),
READONLY: 'true',
};
if (caseSensitiveEmail) {
env.CASE_SENSITIVE_EMAIL = 'true';
Expand Down
9 changes: 4 additions & 5 deletions server/app-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import DynamoDB from 'aws-sdk/clients/dynamodb';
import { Request } from 'express';
import { isValidEmail } from './users/model';
import { assert } from 'console';
import { getOfficeId, isValidOfficeId } from './getOffices';
import { isValidOfficeId } from './getOffices';
import { Arrays } from 'collection-fns';
import { UserType } from 'aws-sdk/clients/cognitoidentityserviceprovider';

Expand All @@ -19,7 +19,7 @@ type CognitoAuthConfig = {
region: string;
};

type OfficeQuotaConfig = { id?: string; name: string; quota: number; parkingQuota?: number };
type OfficeQuotaConfig = { id: string; name: string; quota: number; parkingQuota?: number };
export type OfficeQuota = Required<OfficeQuotaConfig>;

const isOfficeQuotaConfigs = (input: any): input is OfficeQuotaConfig[] =>
Expand All @@ -30,7 +30,7 @@ const isOfficeQuotaConfigs = (input: any): input is OfficeQuotaConfig[] =>
o !== null &&
typeof o.name === 'string' &&
typeof o.quota === 'number' &&
(typeof o.id === 'undefined' || typeof o.id === 'string') &&
typeof o.id === 'string' &&
(typeof o.parkingQuota === 'undefined' || typeof o.parkingQuota === 'number')
);

Expand All @@ -54,14 +54,13 @@ export type Config = {
readonly?: boolean;
};

const parseOfficeQuotas = (OFFICE_QUOTAS: string) => {
const parseOfficeQuotas = (OFFICE_QUOTAS: string): OfficeQuota[] => {
const officeQuotaConfigs = JSON.parse(OFFICE_QUOTAS);
if (!isOfficeQuotaConfigs(officeQuotaConfigs)) {
throw new Error('Invalid office quotas in OFFICE_QUOTAS');
}
const officeQuotas = officeQuotaConfigs.map((o) => ({
...o,
id: o.id ?? getOfficeId(o.name),
parkingQuota: o.parkingQuota ?? 0,
}));
const invalidIds = officeQuotas.map((o) => o.id).filter((id) => !isValidOfficeId(id));
Expand Down
2 changes: 1 addition & 1 deletion server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const configureApp = (config: Config) => {
app.get('/api/config', (req, res, next) => {
try {
const clientConfig = {
version: '1.2.0',
version: '2.0.0',
showTestBanner: config.showTestBanner,
auth:
config.authConfig.type === 'cognito'
Expand Down
6 changes: 3 additions & 3 deletions server/bookings/createBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const createBooking = async (
const newBooking = <BookingsModel>{
id,
parking: request.parking ?? false,
office: requestedOffice.name,
officeId: requestedOffice.id,
date: request.date,
user: request.user,
...('created' in request ? { id: request.id, created: request.created } : {}),
Expand Down Expand Up @@ -130,7 +130,7 @@ export const createBooking = async (
audit('2.1:DecrementingOfficeBookingCount');
await decrementOfficeBookingCount(
config,
requestedOffice.name,
requestedOffice.id,
newBooking.date,
newBooking.parking
);
Expand All @@ -151,7 +151,7 @@ export const createBooking = async (
audit('3.1:DecremetingOfficeBookingCount');
await decrementOfficeBookingCount(
config,
requestedOffice.name,
requestedOffice.id,
newBooking.date,
newBooking.parking
);
Expand Down
4 changes: 2 additions & 2 deletions server/bookings/deleteBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const audit = (step: string, details?: any) =>
const canManageBooking = (authUser: User, booking: BookingsModel) =>
authUser.permissions.canManageAllBookings ||
authUser.permissions.officesCanManageBookingsFor.find(
(office) => office.name === booking.office
(office) => office.id === booking.officeId
) !== undefined;

export const deleteBooking = async (
Expand Down Expand Up @@ -63,7 +63,7 @@ export const deleteBooking = async (

try {
audit('2:DecrementingOfficeBookingCount');
await decrementOfficeBookingCount(config, booking.office, booking.date, booking.parking);
await decrementOfficeBookingCount(config, booking.officeId, booking.date, booking.parking);
audit('3:DecrementingUserBookingCount');
await decrementUserBookingCount(config, booking.user, startOfWeek);
} catch (err) {
Expand Down
2 changes: 1 addition & 1 deletion server/bookings/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const mapBooking = (config: Config, booking: DbBooking): Booking => ({
created: booking.created,
user: booking.user,
date: booking.date,
office: Arrays.get(config.officeQuotas, (office) => office.name === booking.office),
office: Arrays.get(config.officeQuotas, (office) => office.id === booking.officeId),
lastCancellation: getBookingLastCancelTime(booking.date),
parking: booking.parking,
});
Expand Down
4 changes: 2 additions & 2 deletions server/bookings/queryBookings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const queryBookings = async (config: Config, currentUser: User, query: Bo
}

const filterBookings = (booking: BookingsModel) =>
(!query.office || booking.office === query.office.name) &&
(!query.office || booking.officeId === query.office.id) &&
(!query.date || booking.date === query.date) &&
(!query.email || booking.user === query.email);

Expand All @@ -35,7 +35,7 @@ export const queryBookings = async (config: Config, currentUser: User, query: Bo
return mapBookings(config, userBookings.filter(filterBookings));
} else if (query.office !== undefined) {
const officeBookings = await queryBookingsDb(config, {
office: query.office.name,
officeId: query.office.id,
date: query.date,
});
return mapBookings(config, officeBookings.filter(filterBookings));
Expand Down
10 changes: 5 additions & 5 deletions server/db/bookings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export interface CreateBookingModel {
id: string;
user: string;
date: string;
office: string;
officeId: string;
parking: boolean;
}

@table('bookings')
@table('bookings-v2')
export class BookingsModel {
@rangeKey()
id!: string;
Expand All @@ -22,7 +22,7 @@ export class BookingsModel {
@attribute({ indexKeyConfigurations: { 'office-date-bookings': 'RANGE' } })
date!: string;
@attribute({ indexKeyConfigurations: { 'office-date-bookings': 'HASH' } })
office!: string;
officeId!: string;
@attribute()
parking!: boolean;
@attribute()
Expand Down Expand Up @@ -53,11 +53,11 @@ export const getUserBookings = async (

export const queryBookings = async (
config: Config,
query: { office: string; date?: string }
query: { officeId: string; date?: string }
): Promise<BookingsModel[]> => {
const mapper = buildMapper(config);
const rows: BookingsModel[] = [];
const mapperQuery: Partial<BookingsModel> = { office: query.office };
const mapperQuery: Partial<BookingsModel> = { officeId: query.officeId };
if (query.date !== undefined) {
mapperQuery.date = query.date;
}
Expand Down
137 changes: 0 additions & 137 deletions server/db/bookingsV2.ts

This file was deleted.

Loading

0 comments on commit 6def234

Please sign in to comment.