Skip to content

Commit

Permalink
Auth check API; close #109
Browse files Browse the repository at this point in the history
  • Loading branch information
Tanja-4732 committed Sep 3, 2019
1 parent b12b077 commit aca7292
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 21 deletions.
56 changes: 56 additions & 0 deletions backend/src/app/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export class Authentication {
Authentication.logout(req, res),
);

this.routes.get("/status", (req: Request, res: Response) =>
this.getStatus(req, res),
);

// Setup JWT keys
this.getJwtKeys();
}
Expand Down Expand Up @@ -251,6 +255,58 @@ export class Authentication {
return;
}

/**
* Handles login-status-check requests
*/
private async getStatus(req: Request, res: Response) {
// Check for missing cookie
if (req.cookies.JWT == undefined) {
res.status(401).json({ authorized: false, reason: "Missing JWT cookie" });
return;
}

/**
* The format of the data coming back from jwt.verify(jwt, pub_key)
*/
type parsedJWT = {
iat: number;
exp: number;
sub: string;
};

/**
* The parsed (and verified) JWT
*/
let verified: parsedJWT;
try {
verified = jwt.verify(req.cookies.JWT, this.JWT_PUBLIC_KEY) as parsedJWT;
} catch (err) {
res.status(400).json({ authorized: false, reason: "JWT invalid" });
return;
}

/**
* The user from the projection
*/
const user = this.es.users.find((user: User) => {
// Find the user in the projection with a matching email
return user.uuid === verified.sub;
});

// Check for not logged in requests
if (user == undefined) {
res.status(401).json({ authorized: false, reason: "No such user" });
return;
}

// Remove sensitive data
delete user.saltedPwdHash;
delete user.totpSecret;

// Send logged in user data
res.json({ authorized: true, user });
}

//
//
// * Old code below; try to reuse
Expand Down
190 changes: 175 additions & 15 deletions backend/src/app/client-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,29 @@ export class Events {
// Get the events of one inventory
this.routes.get(
"/:inventoryUuid",
this.checkFor0,
this.checkForManagementEventLogs,
(req: Request, res: Response) => this.getInventoryEvents(req, res),
);

// Add an event to an inventory
this.routes.post("/", this.checkFor0, (req: Request, res: Response) =>
this.appendInventoryEvent(req, res),
this.routes.post(
"/",
this.checkForManagementEventLogs,
(req: Request, res: Response) => this.appendInventoryEvent(req, res),
);

// Return an error for an empty get
this.routes.get("/", this.emptyGet);
}

/**
* Check for the management inventory uuids
* Check for the management inventory uuids, and deny access to them
*/
private checkFor0(req: Request, res: Response, next: NextFunction) {
private checkForManagementEventLogs(
req: Request,
res: Response,
next: NextFunction,
) {
if (
req.body.inventoryUuid == ServerEvents.authorizationEventStreamUuid ||
req.body.inventoryUuid == ServerEvents.authenticationEventStreamUuid
Expand Down Expand Up @@ -96,9 +102,9 @@ export class Events {
VALUES ($1, $2, $3)
`,
[
req.params.inventoryUuid,
(req.body as ev).date,
(req.body as ev).data,
(req.body as Event).inventoryUuid,
(req.body as Event).date,
(req.body as Event).data,
],
);

Expand All @@ -116,18 +122,172 @@ export class Events {
}

/**
* How a transmitted event should look like
* The data structure of an event
*/
interface ev {
interface Event {
/**,
* The date of the event
*/
date: Date;

/**
* The date (as an ISO string) at which the event occurred
* The uuid of the inventory-event-stream this event belongs to
*/
date: string;
inventoryUuid: string;

/**
* Data about the inventory
* The data of the event
*/
data: {};
data: {
/**
* The uuid of the item this event is about
* This information is redundant (but still required) on inventory events
*/
uuid: string;

/**
* The uuid of the user who issued this event
*/
userUuid: string;

/**
* Defines what type of item is this event about
*/
itemType: itemType;

/**
* Defines what type of operation was performed
*/
crudType: crudType;

/**
* The inventory-specific data (if this event is about an inventory)
*/
inventoryData?: {
/**
* The name of this inventory
*/
name?: string;

/**
* The uuid of the owner of this inventory
*/
ownerUuid?: string;

/**
* An array of users who have the admin privilege for this inventory
*/
adminsUuids?: string[];

/**
* An array of user uuids who have the write privilege for this inventory
*/
writeablesUuids?: string[];

/**
* An array of user uuids who have the read privilege for this inventory
*/
readablesUuids?: string[];

/**
* The date of the creation of this inventory
*
* This field may only be set in an inventory-created event
*/
createdOn?: Date;
};
/**
* The category-specific data (if this event is about a category)
*/
categoryData?: {
/**
* The name of the category
*/
name?: string;

/**
* The parent-category of this category
*
* Top-level categories are their own parent
*/
parentUuid?: string;

/**
* The date of the creation of this category
*
* This field may only be set in an category-created event
*/
createdOn?: Date;
};

/**
* The thing-specific data (if this event is about a thing)
*/
thingData?: {
/**
* The name of the thing
*/
name: string;

// TODO add the userId to the event
/**
* The date of the creation of this category
*
* This field may only be set in an category-created event
*/
createdOn?: Date;
};

/**
* The stock-specific data (if this event is about a stock)
*/
stockData?: {
/**
* The expiration date of the stock
*/
exDate?: Date;

/**
* How many days after the opening of this stock is it still usable?
*/
useUpIn?: number;

/**
* Text description of the quantity of the stock
*/
quantity?: string;

/**
* When was this stock opened?
*/
openedOn: Date;

/**
* The date of the creation of this category
*
* This field may only be set in an category-created event
*/
createdOn?: Date;
};
};
}

/**
* Used to describe on which type of item an operation was performed on
*/
enum itemType {
INVENTORY = "inventory",
CATEGORY = "category",
THING = "thing",
STOCK = "stock",
}

/**
* Used to describe which type of operation was performed
*
* (read is excluded from this list since it doesn't affect the data)
*/
enum crudType {
CREATE = "create",
UPDATE = "update",
DELETE = "delete",
}
4 changes: 1 addition & 3 deletions frontend/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@
}
],
"baseHref": "/",
"sourceMap": true,
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json"
"sourceMap": true
}
}
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ import { environment } from "../environments/environment";
MatSlideToggleModule,
ZXingScannerModule,
ServiceWorkerModule.register("ngsw-worker.js", {
// enabled: environment.production
enabled: true
enabled: environment.production
// enabled: true
})
],
providers: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class EventSourcingService {
public async appendEventToInventoryStream(event: Event): Promise<void> {
try {
const res: Event[] = await this.api
.put<Event[]>(this.baseUrl + "/events/" + event.inventoryUuid, event)
.put<Event[]>(this.baseUrl + "/events/", event)
.toPromise();

EventSourcingService.eventLogs[event.inventoryUuid].push(event);
Expand Down

0 comments on commit aca7292

Please sign in to comment.