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
84 changes: 37 additions & 47 deletions packages/backend/src/actors/FingerprintStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,11 @@ export class FingerprintStore extends SubscribableActor<Fingerprint, Fingerprint
}
const result = await FingerprintStoreMessages.match<Promise<FingerprintStoreResult>>(message, {
StoreFingerprint: async fingerprint => {
this.state = await create(this.state, async draft => {
const currentFingerprint = (await this.getEntity(fingerprint.uid)).orElse({} as Fingerprint);
fingerprint.updated = toTimestamp();
const newFingerprint = { ...currentFingerprint, ...fingerprint };
draft.cache.set(fingerprint.uid, newFingerprint);
logger.debug(`Storing new fingerprint ${JSON.stringify(newFingerprint)}`);
this.storeEntity(newFingerprint);
});
const currentFingerprint = (await this.getEntity(fingerprint.uid)).orElse({} as Fingerprint);
fingerprint.updated = toTimestamp();
const newFingerprint = { ...currentFingerprint, ...fingerprint };
logger.debug(`Storing new fingerprint ${JSON.stringify(newFingerprint)}`);
await this.storeEntity(newFingerprint);
return unit();
},
Get: async id => {
Expand All @@ -66,49 +63,42 @@ export class FingerprintStore extends SubscribableActor<Fingerprint, Fingerprint
return Promise.resolve(retVal)
},
Block: async id => {
const mbFingerprint = await this.getEntity(id)
const {uid} = await this.ask<UserStoreMessage, User>("actors://recapp-backend/UserStore", UserStoreMessages.GetByFingerprint(id));
return mbFingerprint.match<Unit|Error>(
fp => {
this.storeEntity({...fp, blocked: true});
this.updateSubscribers({...fp, blocked: true})
if (uid)
this.send("actors://recapp-backend/UserStore", UserStoreMessages.Update({ uid, active: false }));
return unit();
},
() => {
return new Error(`Unknown fingerprint id ${id}`);
}
)
const fp = (await this.getEntity(id)).orUndefined();
if (!fp) {
return new Error(`Unknown fingerprint id ${id}`);
}
const { uid } = await this.ask<UserStoreMessage, User>("actors://recapp-backend/UserStore", UserStoreMessages.GetByFingerprint(id));
const updated = { ...fp, blocked: true };
await this.storeEntity(updated);
this.updateSubscribers(updated);
if (uid) {
this.send("actors://recapp-backend/UserStore", UserStoreMessages.Update({ uid, active: false }));
}
return unit();
},
Unblock: async id => {
const mbFingerprint = await this.getEntity(id)
const {uid} = await this.ask<UserStoreMessage, User>("actors://recapp-backend/UserStore", UserStoreMessages.GetByFingerprint(id));
return mbFingerprint.match<Unit|Error>(
fp => {
this.storeEntity({...fp, blocked: false});
this.updateSubscribers({...fp, blocked: false})
if (uid)
this.send("actors://recapp-backend/UserStore", UserStoreMessages.Update({ uid, active: true }));
return unit();
},
() => {
return new Error(`Unknown fingerprint id ${id}`);
}
)
const fp = (await this.getEntity(id)).orUndefined();
if (!fp) {
return new Error(`Unknown fingerprint id ${id}`);
}
const { uid } = await this.ask<UserStoreMessage, User>("actors://recapp-backend/UserStore", UserStoreMessages.GetByFingerprint(id));
const updated = { ...fp, blocked: false };
await this.storeEntity(updated);
this.updateSubscribers(updated);
if (uid) {
this.send("actors://recapp-backend/UserStore", UserStoreMessages.Update({ uid, active: true }));
}
return unit();
},
IncreaseCount: async ({fingerprint, userUid, initialQuiz}) => {
const mbFingerprint = await this.getEntity(fingerprint)
return mbFingerprint.match<Unit|Error>(
fp => {
this.storeEntity({...fp, usageCount: fp.usageCount + 1, lastSeen: toTimestamp(), userUid, initialQuiz: initialQuiz ?? fp.initialQuiz});
this.updateSubscribers({...fp, usageCount: fp.usageCount + 1, lastSeen: toTimestamp(), userUid, initialQuiz: initialQuiz ?? fp.initialQuiz})
return unit();
},
() => {
return new Error(`Unknown fingerprint id ${fingerprint}`);
}
)
const fp = (await this.getEntity(fingerprint)).orUndefined();
if (!fp) {
return new Error(`Unknown fingerprint id ${fingerprint}`);
}
const updated = { ...fp, usageCount: fp.usageCount + 1, lastSeen: toTimestamp(), userUid, initialQuiz: initialQuiz ?? fp.initialQuiz };
await this.storeEntity(updated);
this.updateSubscribers(updated);
return unit();
},
GetMostRecent: async () => {
const db = await this.connector.db();
Expand Down
10 changes: 5 additions & 5 deletions packages/backend/src/actors/SessionStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ export class SessionStore extends StoringActor<Session, SessionStoreMessage, Ses
public async receive(from: ActorRef, message: SessionStoreMessage): Promise<SessionStoreResult> {
const result = await SessionStoreMessages.match<Promise<SessionStoreResult>>(message, {
StoreSession: async session => {
this.state = await create(this.state, async draft => {
const currentSession = (await this.getEntity(session.uid)).orElse({} as Session);
const currentSession = (await this.getEntity(session.uid)).orElse({} as Session);
session.updated = toTimestamp();
const newSession = { ...currentSession, ...session };
this.state = create(this.state, draft => {
if (session.actorSystem) {
draft.clientIndex.set(session.actorSystem, session.uid);
}
session.updated = toTimestamp();
const newSession = { ...currentSession, ...session };
draft.cache.set(session.uid, newSession);
this.storeEntity(newSession);
});
await this.storeEntity(newSession);
return unit();
},
CheckSession: async userId => {
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/actors/StatisticsActor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export class StatisticsActor extends SubscribableActor<
);
// console.log("STATS", stats);
this.logger.info(`STATS stored quizId=${String(this.uid)}`);
this.storeEntity(stats);
await this.storeEntity(stats);
for (const [subscriber] of this.state.collectionSubscribers) {
this.send(subscriber, new StatisticsUpdateMessage(stats));
}
Expand Down
44 changes: 23 additions & 21 deletions packages/backend/src/actors/UserStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,26 +353,6 @@ export class UserStore extends SubscribableActor<User, UserStoreMessage, ResultT
newUser.updated = toTimestamp();
draft.cache.set(userToStore.uid, newUser);

// If the role has changed, also update the session store
if (oldUser.role !== newUser.role) {
(
this.ask(
createActorUri("SessionStore"),
SessionStoreMessages.GetSessionForUserId(newUser.uid)
) as Promise<Session>
)
.then((session: Session) => {
session.role = newUser.role;
this.send(createActorUri("SessionStore"), SessionStoreMessages.StoreSession(session));
})
.catch((e: unknown) => {
this.logger.error(
`Failed to update session role for user ${String(newUser.uid)}: ` +
`${e instanceof Error ? e.stack : String(e)}`
);
});
}

for (const [subscriber, subscription] of this.state.collectionSubscribers) {
this.send(
subscriber,
Expand All @@ -389,8 +369,30 @@ export class UserStore extends SubscribableActor<User, UserStoreMessage, ResultT
});
// console.log("Updated user", newUser);
this.logger.info(`USERSTORE updated user uid=${String((newUser as any)?.uid ?? "?")}`);
return this.storeEntity(newUser)
const storeResult = await this.storeEntity(newUser)
.then(() => newUser)
.catch(error => error as Error);
if (!(storeResult instanceof Error) && oldUser.role !== newUser.role) {
try {
const sessionOrError = await this.ask(
createActorUri("SessionStore"),
SessionStoreMessages.GetSessionForUserId(newUser.uid)
);
if (!(sessionOrError instanceof Error)) {
const session = sessionOrError as Session;
session.role = newUser.role;
await this.ask(
createActorUri("SessionStore"),
SessionStoreMessages.StoreSession(session)
);
}
} catch (e: unknown) {
this.logger.error(
`Failed to update session role for user ${String(newUser.uid)}: ` +
`${e instanceof Error ? e.stack : String(e)}`
);
}
}
return storeResult;
};
}
2 changes: 1 addition & 1 deletion packages/frontend/src/actors/CurrentQuizActor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ export class CurrentQuizActor extends StatefulActor<MessageType, Unit | boolean
g.questions = g.questions.filter(q => q !== id);
return g;
});
await this.send(
await this.ask(
actorUris.QuizActor,
QuizActorMessages.Update({ uid: this.state.quiz.uid, groups })
);
Expand Down
5 changes: 5 additions & 0 deletions packages/frontend/src/actors/SharingActor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ export class SharingActor extends StatefulActor<SharingMessage, Unit, SharingSta
draft.errors.push({ id: toId(v4()), queryNotFound: query });
});
}
})
.catch(() => {
this.updateState(draft => {
draft.errors.push({ id: toId(v4()), queryNotFound: query });
});
});
},
Clear: () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const ChangeNicknameModal: React.FC<Props> = ({ show, defaultValue, onClo
s
.ask("actors://recapp-backend/UserStore", UserStoreMessages.IsNicknameUnique(newValue))
.then(result => !result && setError(i18n._("error-nickname-already-used")))
.catch(() => { /* network error — skip uniqueness check */ })
);
}
};
Expand Down
Loading