File tree Expand file tree Collapse file tree 16 files changed +97
-32
lines changed
authentication/verify-email Expand file tree Collapse file tree 16 files changed +97
-32
lines changed Original file line number Diff line number Diff line change @@ -61,17 +61,27 @@ export const landing =
6161
6262 // Note that we don't need to check isAuthorized here because we are authorised
6363 // by the user clicking the verification link.
64- const resultantEvents = verifyEmail . process ( {
64+ const resultantEvents = await verifyEmail . process ( {
6565 events : resourceEvents . right . events ,
6666 command : {
6767 emailAddress : decoded . right . emailAddress ,
6868 memberNumber : decoded . right . memberNumber ,
6969 actor : { 'tag' : 'system' }
70- }
71- } ) ;
70+ } ,
71+ deps,
72+ } ) ( ) ;
73+
74+ if ( E . isLeft ( resultantEvents ) ) {
75+ deps . logger . error (
76+ resultantEvents . left ,
77+ 'Failed to process verification link'
78+ ) ;
79+ res . send ( invalidLink ( ) ) ;
80+ return ;
81+ }
7282
73- if ( O . isSome ( resultantEvents ) ) {
74- const commitEvent = await deps . commitEvent ( resource , resourceEvents . right . version ) ( resultantEvents . value ) ( ) ;
83+ if ( O . isSome ( resultantEvents . right ) ) {
84+ const commitEvent = await deps . commitEvent ( resource , resourceEvents . right . version ) ( resultantEvents . right . value ) ( ) ;
7585 if ( E . isLeft ( commitEvent ) ) {
7686 deps . logger . error (
7787 commitEvent . left ,
Original file line number Diff line number Diff line change @@ -3,6 +3,7 @@ import * as RA from 'fp-ts/ReadonlyArray';
33import * as t from 'io-ts' ;
44import * as tt from 'io-ts-types' ;
55import * as O from 'fp-ts/Option' ;
6+ import * as TE from 'fp-ts/TaskEither' ;
67import { pipe } from 'fp-ts/lib/function' ;
78import { Command } from '../command' ;
89import { isAdminOrSuperUser } from '../is-admin-or-super-user' ;
@@ -16,10 +17,10 @@ export type AddOwner = t.TypeOf<typeof codec>;
1617
1718const process : Command < AddOwner > [ 'process' ] = input => {
1819 if ( input . events . length === 0 ) {
19- return O . none ;
20+ return TE . right ( O . none ) ;
2021 }
2122 if ( pipe ( input . events , RA . some ( isEventOfType ( 'AreaRemoved' ) ) ) ) {
22- return O . none ;
23+ return TE . right ( O . none ) ;
2324 }
2425
2526 const happyPathEvent = pipe (
@@ -39,7 +40,8 @@ const process: Command<AddOwner>['process'] = input => {
3940 case 'OwnerRemoved' :
4041 return happyPathEvent ;
4142 }
42- } )
43+ } ) ,
44+ TE . right
4345 ) ;
4446} ;
4547
Original file line number Diff line number Diff line change 11import { constructEvent , isEventOfType } from '../../types' ;
22import * as RA from 'fp-ts/ReadonlyArray' ;
3+ import * as TE from 'fp-ts/TaskEither' ;
34import * as t from 'io-ts' ;
45import * as tt from 'io-ts-types' ;
56import * as O from 'fp-ts/Option' ;
@@ -15,15 +16,16 @@ type RemoveArea = t.TypeOf<typeof codec>;
1516
1617const process : Command < RemoveArea > [ 'process' ] = input => {
1718 if ( input . events . length === 0 ) {
18- return O . none ;
19+ return TE . right ( O . none ) ;
1920 }
2021 return pipe (
2122 input . events ,
2223 RA . filter ( isEventOfType ( 'AreaRemoved' ) ) ,
2324 RA . match (
2425 ( ) => O . some ( constructEvent ( 'AreaRemoved' ) ( input . command ) ) ,
2526 ( ) => O . none
26- )
27+ ) ,
28+ TE . right ,
2729 ) ;
2830} ;
2931
Original file line number Diff line number Diff line change 11import * as t from 'io-ts' ;
22import * as tt from 'io-ts-types' ;
33import * as O from 'fp-ts/Option' ;
4+ import * as TE from 'fp-ts/TaskEither' ;
45import { Command } from '../command' ;
56import { isAdminOrSuperUser } from '../is-admin-or-super-user' ;
67import { pipe } from 'fp-ts/lib/function' ;
@@ -16,7 +17,7 @@ type RemoveOwner = t.TypeOf<typeof codec>;
1617
1718const process : Command < RemoveOwner > [ 'process' ] = input => {
1819 if ( pipe ( input . events , RA . some ( isEventOfType ( 'AreaRemoved' ) ) ) ) {
19- return O . none ;
20+ return TE . right ( O . none ) ;
2021 }
2122
2223 return pipe (
@@ -36,7 +37,8 @@ const process: Command<RemoveOwner>['process'] = input => {
3637 } ) ,
3738 RA . last ,
3839 O . filter ( isEventOfType ( 'OwnerAdded' ) ) ,
39- O . map ( ( ) => constructEvent ( 'OwnerRemoved' ) ( input . command ) )
40+ O . map ( ( ) => constructEvent ( 'OwnerRemoved' ) ( input . command ) ) ,
41+ TE . right ,
4042 ) ;
4143}
4244
Original file line number Diff line number Diff line change @@ -3,6 +3,7 @@ import * as RA from 'fp-ts/ReadonlyArray';
33import * as t from 'io-ts' ;
44import * as tt from 'io-ts-types' ;
55import * as O from 'fp-ts/Option' ;
6+ import * as TE from 'fp-ts/TaskEither' ;
67import { pipe } from 'fp-ts/lib/function' ;
78import { Command } from '../command' ;
89import { isAdminOrSuperUser } from '../is-admin-or-super-user' ;
@@ -21,7 +22,8 @@ const process: Command<AddEquipment>['process'] = input =>
2122 RA . match (
2223 ( ) => O . some ( constructEvent ( 'EquipmentAdded' ) ( input . command ) ) ,
2324 ( ) => O . none
24- )
25+ ) ,
26+ TE . right
2527 ) ;
2628
2729const resource : Command < AddEquipment > [ 'resource' ] = command => ( {
Original file line number Diff line number Diff line change 11import * as t from 'io-ts' ;
22import * as tt from 'io-ts-types' ;
33import * as O from 'fp-ts/Option' ;
4+ import * as TE from 'fp-ts/TaskEither' ;
45import { DomainEvent , constructEvent } from '../../types' ;
56import { Actor } from '../../types/actor' ;
67import { Command , WithActor } from '../command' ;
@@ -18,9 +19,9 @@ export type RegisterTrainingSheet = t.TypeOf<typeof codec>;
1819const process = ( input : {
1920 command : WithActor < RegisterTrainingSheet > ;
2021 events : ReadonlyArray < DomainEvent > ;
21- } ) : O . Option < DomainEvent > =>
22+ } ) =>
2223 // No idempotency check required here currently. If the training sheet already matches the current then we still record the duplicate event.
23- O . some ( constructEvent ( 'EquipmentTrainingSheetRegistered' ) ( input . command ) ) ;
24+ TE . right ( O . some ( constructEvent ( 'EquipmentTrainingSheetRegistered' ) ( input . command ) ) ) ;
2425
2526const resource = ( command : RegisterTrainingSheet ) => ( {
2627 type : 'Equipment' ,
Original file line number Diff line number Diff line change 11import * as t from 'io-ts' ;
22import * as tt from 'io-ts-types' ;
33import * as O from 'fp-ts/Option' ;
4+ import * as TE from 'fp-ts/TaskEither' ;
45import { DomainEvent , constructEvent } from '../../types' ;
56import { Actor } from '../../types/actor' ;
67import { Command , WithActor } from '../command' ;
@@ -17,8 +18,8 @@ type RemoveTrainingSheet = t.TypeOf<typeof codec>;
1718const process = ( input : {
1819 command : WithActor < RemoveTrainingSheet > ;
1920 events : ReadonlyArray < DomainEvent > ;
20- } ) : O . Option < DomainEvent > =>
21- O . some ( constructEvent ( 'EquipmentTrainingSheetRemoved' ) ( input . command ) ) ;
21+ } ) =>
22+ TE . right ( O . some ( constructEvent ( 'EquipmentTrainingSheetRemoved' ) ( input . command ) ) ) ;
2223
2324const resource = ( command : RemoveTrainingSheet ) => ( {
2425 type : 'Equipment' ,
Original file line number Diff line number Diff line change 11import * as O from 'fp-ts/Option' ;
2+ import * as TE from 'fp-ts/TaskEither' ;
23import * as t from 'io-ts' ;
34import { Command } from '../command' ;
45import { EmailAddressCodec , constructEvent } from '../../types' ;
@@ -18,22 +19,22 @@ const process: Command<VerifyMemberEmail>['process'] = input => {
1819 input . command . memberNumber
1920 ) ;
2021 if ( state === undefined ) {
21- return O . none ;
22+ return TE . right ( O . none ) ;
2223 }
2324
2425 const emailAddress = normaliseEmailAddress ( input . command . emailAddress ) ;
2526 const email = state . emails [ emailAddress ] ;
2627 if ( ! email || email . verified ) {
27- return O . none ;
28+ return TE . right ( O . none ) ;
2829 }
2930
30- return O . some (
31+ return TE . right ( O . some (
3132 constructEvent ( 'MemberEmailVerified' ) ( {
3233 actor : input . command . actor ,
3334 memberNumber : input . command . memberNumber ,
3435 email : input . command . emailAddress ,
3536 } )
36- ) ;
37+ ) ) ;
3738} ;
3839
3940const resource = ( ) => ( {
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ import {constructEvent} from '../../types';
22import * as t from 'io-ts' ;
33import * as tt from 'io-ts-types' ;
44import * as O from 'fp-ts/Option' ;
5+ import * as TE from 'fp-ts/TaskEither' ;
56import { Command } from '../command' ;
67import { isAdminOrSuperUser } from '../is-admin-or-super-user' ;
78import { resource } from './resource' ;
@@ -13,7 +14,7 @@ const codec = t.strict({
1314export type DeclareSuperUserCommand = t . TypeOf < typeof codec > ;
1415
1516const process : Command < DeclareSuperUserCommand > [ 'process' ] = input =>
16- O . some ( constructEvent ( 'SuperUserDeclared' ) ( input . command ) ) ;
17+ TE . right ( O . some ( constructEvent ( 'SuperUserDeclared' ) ( input . command ) ) ) ;
1718
1819export const declare : Command < DeclareSuperUserCommand > = {
1920 process,
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ import {constructEvent} from '../../types';
22import * as t from 'io-ts' ;
33import * as tt from 'io-ts-types' ;
44import * as O from 'fp-ts/Option' ;
5+ import * as TE from 'fp-ts/TaskEither' ;
56import { Command } from '../command' ;
67import * as RA from 'fp-ts/ReadonlyArray' ;
78import { isAdminOrSuperUser } from '../is-admin-or-super-user' ;
@@ -27,7 +28,8 @@ const process: Command<RevokeSuperUser>['process'] = input =>
2728 event . type === 'SuperUserDeclared'
2829 ? O . some ( constructEvent ( 'SuperUserRevoked' ) ( input . command ) )
2930 : O . none
30- )
31+ ) ,
32+ TE . right
3133 ) ;
3234
3335export const revoke : Command < RevokeSuperUser > = {
You can’t perform that action at this time.
0 commit comments