@stevenkellner/team-conduct-api 1.0.36 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/firebase/FirebaseConfiguration.d.ts +45 -1
- package/lib/src/firebase/FirebaseConfiguration.js +44 -0
- package/lib/src/firebase/Firestore.d.ts +196 -0
- package/lib/src/firebase/Firestore.js +235 -0
- package/lib/src/{FirestoreScheme.d.ts → firebase/FirestoreScheme.d.ts} +15 -1
- package/lib/src/firebase/Messaging.d.ts +64 -0
- package/lib/src/firebase/checkAuthentication.d.ts +37 -0
- package/lib/src/{checkAuthentication.js → firebase/checkAuthentication.js} +26 -1
- package/lib/src/firebase/index.d.ts +4 -0
- package/lib/src/firebase/index.js +4 -0
- package/lib/src/firebase/pushNotification.d.ts +39 -0
- package/lib/src/firebase/pushNotification.js +88 -0
- package/lib/src/functions/fine/add.d.ts +10 -13
- package/lib/src/functions/fine/add.js +3 -30
- package/lib/src/functions/fine/delete.d.ts +10 -13
- package/lib/src/functions/fine/delete.js +3 -27
- package/lib/src/functions/fine/update.d.ts +10 -13
- package/lib/src/functions/fine/update.js +3 -28
- package/lib/src/functions/fineTemplate/add.d.ts +6 -9
- package/lib/src/functions/fineTemplate/add.js +3 -12
- package/lib/src/functions/fineTemplate/delete.d.ts +6 -9
- package/lib/src/functions/fineTemplate/delete.js +3 -12
- package/lib/src/functions/fineTemplate/update.d.ts +6 -9
- package/lib/src/functions/fineTemplate/update.js +3 -12
- package/lib/src/functions/invitation/getInvitation.d.ts +40 -43
- package/lib/src/functions/invitation/getInvitation.js +57 -88
- package/lib/src/functions/invitation/invite.d.ts +1 -2
- package/lib/src/functions/invitation/invite.js +3 -18
- package/lib/src/functions/invitation/register.d.ts +6 -11
- package/lib/src/functions/invitation/register.js +3 -39
- package/lib/src/functions/invitation/withdraw.d.ts +1 -2
- package/lib/src/functions/invitation/withdraw.js +3 -13
- package/lib/src/functions/notification/register.d.ts +7 -10
- package/lib/src/functions/notification/register.js +3 -15
- package/lib/src/functions/notification/subscribe.d.ts +8 -11
- package/lib/src/functions/notification/subscribe.js +3 -14
- package/lib/src/functions/paypalMe/edit.d.ts +6 -9
- package/lib/src/functions/paypalMe/edit.js +3 -14
- package/lib/src/functions/person/add.d.ts +7 -10
- package/lib/src/functions/person/add.js +3 -12
- package/lib/src/functions/person/delete.d.ts +6 -9
- package/lib/src/functions/person/delete.js +3 -14
- package/lib/src/functions/person/update.d.ts +7 -10
- package/lib/src/functions/person/update.js +3 -13
- package/lib/src/functions/team/new.d.ts +9 -12
- package/lib/src/functions/team/new.js +3 -22
- package/lib/src/functions/user/kickout.d.ts +6 -9
- package/lib/src/functions/user/kickout.js +3 -25
- package/lib/src/functions/user/login.d.ts +1 -2
- package/lib/src/functions/user/login.js +3 -13
- package/lib/src/functions/user/roleEdit.d.ts +8 -11
- package/lib/src/functions/user/roleEdit.js +3 -18
- package/lib/src/index.d.ts +0 -5
- package/lib/src/index.js +0 -5
- package/lib/src/locales/de.d.ts +10 -67
- package/lib/src/locales/de.js +8 -0
- package/lib/src/locales/en.d.ts +10 -0
- package/lib/src/locales/en.js +19 -2
- package/lib/src/types/Configuration.d.ts +33 -15
- package/lib/src/types/Configuration.js +24 -12
- package/lib/src/types/Currency.d.ts +20 -0
- package/lib/src/types/Currency.js +19 -0
- package/lib/src/types/Fine.d.ts +41 -0
- package/lib/src/types/Fine.js +32 -0
- package/lib/src/types/FineAmount.d.ts +160 -9
- package/lib/src/types/FineAmount.js +128 -7
- package/lib/src/types/FineTemplate.d.ts +41 -0
- package/lib/src/types/FineTemplate.js +32 -0
- package/lib/src/types/FineTemplateRepetition.d.ts +72 -10
- package/lib/src/types/FineTemplateRepetition.js +66 -12
- package/lib/src/types/Invitation.d.ts +48 -0
- package/lib/src/types/Invitation.js +39 -0
- package/lib/src/types/Locale.d.ts +16 -0
- package/lib/src/types/Locale.js +16 -0
- package/lib/src/types/Localization.d.ts +74 -74
- package/lib/src/types/Localization.js +80 -41
- package/lib/src/types/MoneyAmount.d.ts +67 -1
- package/lib/src/types/MoneyAmount.js +62 -0
- package/lib/src/types/NotificationProperties.d.ts +70 -9
- package/lib/src/types/NotificationProperties.js +49 -5
- package/lib/src/types/PayedState.d.ts +25 -9
- package/lib/src/types/PayedState.js +17 -27
- package/lib/src/types/Person.d.ts +45 -0
- package/lib/src/types/Person.js +36 -0
- package/lib/src/types/PersonPrivateProperties.d.ts +28 -0
- package/lib/src/types/PersonPrivateProperties.js +25 -0
- package/lib/src/types/PersonSignInProperties.d.ts +30 -0
- package/lib/src/types/PersonSignInProperties.js +27 -0
- package/lib/src/types/Pluralization.d.ts +46 -0
- package/lib/src/types/Pluralization.js +46 -0
- package/lib/src/types/Team.d.ts +38 -0
- package/lib/src/types/Team.js +29 -0
- package/lib/src/types/User.d.ts +68 -3
- package/lib/src/types/User.js +59 -5
- package/lib/src/types/UserRole.d.ts +26 -4
- package/lib/src/types/UserRole.js +25 -9
- package/lib/src/types/index.d.ts +2 -0
- package/lib/src/types/index.js +2 -0
- package/lib/test/firebase/FirebaseConfiguration.test.js +155 -0
- package/lib/test/firebase/Firestore.test.js +46 -0
- package/lib/test/firebase/checkAuthentication.test.d.ts +1 -0
- package/lib/test/firebase/checkAuthentication.test.js +305 -0
- package/lib/test/firebase/firebase-utils.d.ts +32 -0
- package/lib/test/firebase/firebase-utils.js +131 -0
- package/lib/test/firebase/pushNotification.test.d.ts +1 -0
- package/lib/test/firebase/pushNotification.test.js +300 -0
- package/lib/test/locales/localization.de.test.d.ts +1 -0
- package/lib/test/locales/localization.de.test.js +144 -0
- package/lib/test/locales/localization.en.test.d.ts +1 -0
- package/lib/test/locales/localization.en.test.js +144 -0
- package/lib/test/types/Configuration.test.d.ts +1 -0
- package/lib/test/types/Configuration.test.js +84 -0
- package/lib/test/types/Currency.test.d.ts +1 -0
- package/lib/test/types/Currency.test.js +41 -0
- package/lib/test/types/Fine.test.d.ts +1 -0
- package/lib/test/types/Fine.test.js +265 -0
- package/lib/test/types/FineAmount.test.d.ts +1 -0
- package/lib/test/types/FineAmount.test.js +445 -0
- package/lib/test/types/FineTemplate.test.d.ts +1 -0
- package/lib/test/types/FineTemplate.test.js +271 -0
- package/lib/test/types/FineTemplateRepetition.test.d.ts +1 -0
- package/lib/test/types/FineTemplateRepetition.test.js +361 -0
- package/lib/test/types/Invitation.test.d.ts +1 -0
- package/lib/test/types/Invitation.test.js +269 -0
- package/lib/test/types/Locale.test.d.ts +1 -0
- package/lib/test/types/Locale.test.js +46 -0
- package/lib/test/types/Localization.test.d.ts +1 -0
- package/lib/test/types/Localization.test.js +241 -0
- package/lib/test/types/MoneyAmount.test.d.ts +1 -0
- package/lib/test/types/MoneyAmount.test.js +276 -0
- package/lib/test/types/NotificationProperties.test.d.ts +1 -0
- package/lib/test/types/NotificationProperties.test.js +258 -0
- package/lib/test/types/PayedState.test.d.ts +1 -0
- package/lib/test/types/PayedState.test.js +105 -0
- package/lib/test/types/Person.test.d.ts +1 -0
- package/lib/test/types/Person.test.js +266 -0
- package/lib/test/types/PersonPrivateProperties.test.d.ts +1 -0
- package/lib/test/types/PersonPrivateProperties.test.js +155 -0
- package/lib/test/types/PersonSignInProperties.test.d.ts +1 -0
- package/lib/test/types/PersonSignInProperties.test.js +208 -0
- package/lib/test/types/Pluralization.test.d.ts +1 -0
- package/lib/test/types/Pluralization.test.js +206 -0
- package/lib/test/types/Team.test.d.ts +1 -0
- package/lib/test/types/Team.test.js +145 -0
- package/lib/test/types/User.test.d.ts +1 -0
- package/lib/test/types/User.test.js +232 -0
- package/lib/test/types/UserRole.test.d.ts +1 -0
- package/lib/test/types/UserRole.test.js +140 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -9
- package/src/firebase/FirebaseConfiguration.ts +49 -1
- package/src/firebase/Firestore.ts +248 -0
- package/src/{FirestoreScheme.ts → firebase/FirestoreScheme.ts} +15 -1
- package/src/firebase/Messaging.ts +64 -0
- package/src/{checkAuthentication.ts → firebase/checkAuthentication.ts} +39 -1
- package/src/firebase/index.ts +5 -0
- package/src/firebase/pushNotification.ts +90 -0
- package/src/functions/fine/add.ts +10 -48
- package/src/functions/fine/delete.ts +9 -43
- package/src/functions/fine/update.ts +10 -44
- package/src/functions/fineTemplate/add.ts +7 -23
- package/src/functions/fineTemplate/delete.ts +7 -23
- package/src/functions/fineTemplate/update.ts +7 -24
- package/src/functions/index.ts +0 -1
- package/src/functions/invitation/getInvitation.ts +81 -118
- package/src/functions/invitation/invite.ts +2 -25
- package/src/functions/invitation/register.ts +9 -60
- package/src/functions/invitation/withdraw.ts +2 -16
- package/src/functions/notification/register.ts +7 -26
- package/src/functions/notification/subscribe.ts +8 -26
- package/src/functions/paypalMe/edit.ts +7 -25
- package/src/functions/person/add.ts +8 -24
- package/src/functions/person/delete.ts +6 -25
- package/src/functions/person/update.ts +8 -25
- package/src/functions/team/new.ts +12 -42
- package/src/functions/user/kickout.ts +8 -41
- package/src/functions/user/login.ts +2 -16
- package/src/functions/user/roleEdit.ts +8 -32
- package/src/index.ts +0 -5
- package/src/locales/de.ts +10 -1
- package/src/locales/en.ts +21 -2
- package/src/types/Configuration.ts +33 -23
- package/src/types/Currency.ts +24 -0
- package/src/types/Fine.ts +41 -0
- package/src/types/FineAmount.ts +162 -11
- package/src/types/FineTemplate.ts +41 -0
- package/src/types/FineTemplateRepetition.ts +75 -17
- package/src/types/Invitation.ts +48 -0
- package/src/types/Locale.ts +20 -0
- package/src/types/Localization.ts +96 -41
- package/src/types/MoneyAmount.ts +67 -1
- package/src/types/NotificationProperties.ts +67 -9
- package/src/types/PayedState.ts +25 -30
- package/src/types/Person.ts +45 -0
- package/src/types/PersonPrivateProperties.ts +28 -1
- package/src/types/PersonSignInProperties.ts +30 -0
- package/src/types/Pluralization.ts +46 -0
- package/src/types/Team.ts +38 -0
- package/src/types/User.ts +70 -4
- package/src/types/UserRole.ts +32 -16
- package/src/types/index.ts +2 -0
- package/lib/src/Firestore.d.ts +0 -24
- package/lib/src/Firestore.js +0 -62
- package/lib/src/checkAuthentication.d.ts +0 -6
- package/lib/src/firebaseFunctionsContext.d.ts +0 -39
- package/lib/src/firebaseFunctionsContext.js +0 -43
- package/lib/src/pushNotification.d.ts +0 -3
- package/lib/src/pushNotification.js +0 -35
- package/lib/test/localization-utils.d.ts +0 -1
- package/lib/test/localization-utils.js +0 -24
- package/lib/test/localization.de.test.js +0 -151
- package/lib/test/localization.en.test.js +0 -145
- package/src/Firestore.ts +0 -75
- package/src/firebaseFunctionsContext.ts +0 -48
- package/src/pushNotification.ts +0 -37
- /package/lib/src/{FirestoreScheme.js → firebase/FirestoreScheme.js} +0 -0
- /package/lib/test/{localization.de.test.d.ts → firebase/FirebaseConfiguration.test.d.ts} +0 -0
- /package/lib/test/{localization.en.test.d.ts → firebase/Firestore.test.d.ts} +0 -0
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { FunctionsError } from '@stevenkellner/firebase-function';
|
|
2
|
-
import { Person, Team, User, UserRole } from '
|
|
2
|
+
import { Person, Team, User, UserRole } from '../types';
|
|
3
3
|
import { Firestore } from './Firestore';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Type representing expected user role requirements.
|
|
7
|
+
*
|
|
8
|
+
* Can be:
|
|
9
|
+
* - A single `UserRole` (user must have this role)
|
|
10
|
+
* - An array of `ExpectedUserRoles` (user must satisfy ALL requirements - logical AND)
|
|
11
|
+
* - An object with `anyOf` property (user must satisfy AT LEAST ONE requirement - logical OR)
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* - `'admin'` - User must be admin
|
|
15
|
+
* - `['member', 'treasurer']` - User must be both member AND treasurer
|
|
16
|
+
* - `{ anyOf: ['admin', 'treasurer'] }` - User must be admin OR treasurer
|
|
17
|
+
*/
|
|
5
18
|
type ExpectedUserRoles =
|
|
6
19
|
| UserRole
|
|
7
20
|
| ExpectedUserRoles[]
|
|
@@ -9,6 +22,13 @@ type ExpectedUserRoles =
|
|
|
9
22
|
anyOf: ExpectedUserRoles[];
|
|
10
23
|
}
|
|
11
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Checks if the user has the required roles according to the expected role requirements.
|
|
27
|
+
*
|
|
28
|
+
* @param userRoles - Array of roles the user currently has
|
|
29
|
+
* @param expectedRoles - The role requirements to check against (supports AND/OR logic)
|
|
30
|
+
* @returns `true` if the user satisfies the role requirements, `false` otherwise
|
|
31
|
+
*/
|
|
12
32
|
function hasUserRoles(userRoles: UserRole[], expectedRoles: ExpectedUserRoles): boolean {
|
|
13
33
|
if (Array.isArray(expectedRoles))
|
|
14
34
|
return expectedRoles.every(expectedRole => hasUserRoles(userRoles, expectedRole));
|
|
@@ -19,6 +39,24 @@ function hasUserRoles(userRoles: UserRole[], expectedRoles: ExpectedUserRoles):
|
|
|
19
39
|
|
|
20
40
|
}
|
|
21
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Validates that a user is authenticated and has the required roles for a specific team.
|
|
44
|
+
*
|
|
45
|
+
* Performs comprehensive authentication checks:
|
|
46
|
+
* 1. Verifies the user is authenticated (rawUserId is not null)
|
|
47
|
+
* 2. Checks that the user exists in the database
|
|
48
|
+
* 3. Confirms the user is a member of the specified team
|
|
49
|
+
* 4. Validates that the person associated with the user exists
|
|
50
|
+
* 5. Ensures the person is signed in (has signInProperties)
|
|
51
|
+
* 6. Verifies the person has the required roles
|
|
52
|
+
*
|
|
53
|
+
* @param rawUserId - The raw user ID string from authentication context (null if not authenticated)
|
|
54
|
+
* @param teamId - The ID of the team to check membership and roles for
|
|
55
|
+
* @param roles - The expected role requirements (supports AND/OR logic via ExpectedUserRoles)
|
|
56
|
+
* @returns The validated User.Id if all checks pass
|
|
57
|
+
* @throws {FunctionsError} 'unauthenticated' - If rawUserId is null
|
|
58
|
+
* @throws {FunctionsError} 'permission-denied' - If any validation check fails
|
|
59
|
+
*/
|
|
22
60
|
export async function checkAuthentication(rawUserId: string | null, teamId: Team.Id, roles: ExpectedUserRoles): Promise<User.Id> {
|
|
23
61
|
if (rawUserId === null)
|
|
24
62
|
throw new FunctionsError('unauthenticated', 'User is not authenticated');
|
package/src/firebase/index.ts
CHANGED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Dictionary } from '@stevenkellner/typescript-common-functionality';
|
|
2
|
+
import { Firestore } from './Firestore';
|
|
3
|
+
import { NotificationProperties, Person, Team } from '../types';
|
|
4
|
+
import { FirebaseConfiguration, BatchResponse, Notification } from '.';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Filters successful tokens from a Firebase Cloud Messaging batch response.
|
|
8
|
+
*
|
|
9
|
+
* Removes tokens that failed due to invalid or unregistered registration tokens,
|
|
10
|
+
* keeping only the tokens that successfully received the notification.
|
|
11
|
+
*
|
|
12
|
+
* @param response - The batch response from Firebase Cloud Messaging
|
|
13
|
+
* @param tokens - The array of device tokens that were sent the notification
|
|
14
|
+
* @returns A dictionary mapping token IDs to their corresponding device tokens for successful deliveries
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Filters out tokens with the following error codes:
|
|
18
|
+
* - `messaging/invalid-registration-token`: The token format is invalid
|
|
19
|
+
* - `messaging/registration-token-not-registered`: The token is no longer registered
|
|
20
|
+
*
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
function successfulTokens(response: BatchResponse, tokens: string[]): Dictionary<NotificationProperties.TokenId, string> {
|
|
24
|
+
const successfulTokens = response.responses
|
|
25
|
+
.map((response, index) => ({
|
|
26
|
+
failed: response.error?.code ==='messaging/invalid-registration-token' || response.error?.code === 'messaging/registration-token-not-registered',
|
|
27
|
+
token: tokens[index]
|
|
28
|
+
}))
|
|
29
|
+
.filter(response => !response.failed)
|
|
30
|
+
.map(response => response.token);
|
|
31
|
+
const tokenDict = new Dictionary<NotificationProperties.TokenId, string>(NotificationProperties.TokenId.builder);
|
|
32
|
+
for (const token of successfulTokens)
|
|
33
|
+
tokenDict.set(NotificationProperties.TokenId.create(token), token);
|
|
34
|
+
return tokenDict;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Sends a push notification to a person if they are subscribed to the topic.
|
|
39
|
+
*
|
|
40
|
+
* Retrieves the person's notification properties, checks their subscription status,
|
|
41
|
+
* sends the notification to all their registered device tokens, and updates their
|
|
42
|
+
* token list to remove any failed tokens.
|
|
43
|
+
*
|
|
44
|
+
* @param teamId - The unique identifier of the team
|
|
45
|
+
* @param personId - The unique identifier of the person
|
|
46
|
+
* @param topic - The notification subscription topic (e.g., 'new-fine', 'fine-reminder', 'fine-state-change')
|
|
47
|
+
* @param notification - The notification content to send
|
|
48
|
+
*
|
|
49
|
+
* @returns A promise that resolves when the notification is sent and person data is updated
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* The function will silently return without sending if:
|
|
53
|
+
* - The person does not exist in the database
|
|
54
|
+
* - The person is not signed in (signInProperties is null)
|
|
55
|
+
* - The person is not subscribed to the specified topic
|
|
56
|
+
*
|
|
57
|
+
* After sending, the person's token list is automatically updated to remove
|
|
58
|
+
* any tokens that are invalid or unregistered, maintaining clean notification data.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* await pushNotification(
|
|
63
|
+
* teamId,
|
|
64
|
+
* personId,
|
|
65
|
+
* 'new-fine',
|
|
66
|
+
* {
|
|
67
|
+
* title: 'New Fine',
|
|
68
|
+
* body: 'You have received a new fine'
|
|
69
|
+
* }
|
|
70
|
+
* );
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export async function pushNotification(teamId: Team.Id, personId: Person.Id, topic: NotificationProperties.Subscription, notification: Notification): Promise<void> {
|
|
74
|
+
|
|
75
|
+
const personSnapshot = await Firestore.shared.person(teamId, personId).snapshot();
|
|
76
|
+
if (!personSnapshot.exists)
|
|
77
|
+
return;
|
|
78
|
+
const person = Person.builder.build(personSnapshot.data);
|
|
79
|
+
|
|
80
|
+
if (person.signInProperties === null || !person.signInProperties.notificationProperties.subscriptions.includes(topic))
|
|
81
|
+
return;
|
|
82
|
+
|
|
83
|
+
const tokens = person.signInProperties.notificationProperties.tokens.values;
|
|
84
|
+
const response = await FirebaseConfiguration.shared.messaging.sendEachForMulticast({
|
|
85
|
+
tokens: tokens,
|
|
86
|
+
notification: notification
|
|
87
|
+
});
|
|
88
|
+
person.signInProperties.notificationProperties.tokens = successfulTokens(response, tokens);
|
|
89
|
+
await Firestore.shared.person(teamId, personId).set(person);
|
|
90
|
+
}
|
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
import { FirebaseFunction
|
|
1
|
+
import { FirebaseFunction } from '@stevenkellner/firebase-function';
|
|
2
2
|
import { Flattable, ObjectTypeBuilder, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
3
|
-
import { Configuration, Fine,
|
|
4
|
-
import { checkAuthentication } from '../../checkAuthentication';
|
|
5
|
-
import { Firestore } from '../../Firestore';
|
|
6
|
-
import { pushNotification } from '../../pushNotification';
|
|
3
|
+
import { Configuration, Fine, Person, Team } from '../../types';
|
|
7
4
|
|
|
5
|
+
export type FineAddFunctionParameters = {
|
|
6
|
+
teamId: Team.Id,
|
|
7
|
+
personId: Person.Id,
|
|
8
|
+
fine: Fine,
|
|
9
|
+
configuration: Configuration
|
|
10
|
+
};
|
|
8
11
|
|
|
9
|
-
export
|
|
12
|
+
export abstract class FineAddFunctionBase extends FirebaseFunction<FineAddFunctionParameters, void> {
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
teamId: Team.Id,
|
|
13
|
-
personId: Person.Id,
|
|
14
|
-
fine: Fine,
|
|
15
|
-
configuration: Configuration
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class FineAddFunction extends FirebaseFunction<FineAddFunction.Parameters, void> {
|
|
20
|
-
|
|
21
|
-
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineAddFunction.Parameters>, FineAddFunction.Parameters>({
|
|
14
|
+
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineAddFunctionParameters>, FineAddFunctionParameters>({
|
|
22
15
|
teamId: Team.Id.builder,
|
|
23
16
|
personId: Person.Id.builder,
|
|
24
17
|
fine: Fine.builder,
|
|
@@ -26,35 +19,4 @@ export class FineAddFunction extends FirebaseFunction<FineAddFunction.Parameters
|
|
|
26
19
|
});
|
|
27
20
|
|
|
28
21
|
public returnTypeBuilder = new ValueTypeBuilder<void>();
|
|
29
|
-
|
|
30
|
-
public async execute(parameters: FineAddFunction.Parameters): Promise<void> {
|
|
31
|
-
|
|
32
|
-
await checkAuthentication(this.userId, parameters.teamId, {
|
|
33
|
-
anyOf: ['fine-manager', 'fine-can-add']
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const fineSnapshot = await Firestore.shared.fine(parameters.teamId, parameters.fine.id).snapshot();
|
|
37
|
-
if (fineSnapshot.exists)
|
|
38
|
-
throw new FunctionsError('already-exists', 'Fine already exists');
|
|
39
|
-
|
|
40
|
-
const personSnapshot = await Firestore.shared.person(parameters.teamId, parameters.personId).snapshot();
|
|
41
|
-
if (!personSnapshot.exists)
|
|
42
|
-
throw new FunctionsError('not-found', 'Person not found');
|
|
43
|
-
const person = Person.builder.build(personSnapshot.data);
|
|
44
|
-
|
|
45
|
-
await Firestore.shared.fine(parameters.teamId, parameters.fine.id).set(parameters.fine);
|
|
46
|
-
|
|
47
|
-
person.fineIds.push(parameters.fine.id);
|
|
48
|
-
await Firestore.shared.person(parameters.teamId, parameters.personId).set(person);
|
|
49
|
-
|
|
50
|
-
Localization.locale = parameters.configuration.locale;
|
|
51
|
-
await pushNotification(parameters.teamId, parameters.personId, 'new-fine', {
|
|
52
|
-
title: Localization.shared.notification.fine.new.title.value({
|
|
53
|
-
reason: parameters.fine.reason
|
|
54
|
-
}),
|
|
55
|
-
body: Localization.shared.notification.fine.new.body.value({
|
|
56
|
-
amount: parameters.fine.amount.formatted(parameters.configuration)
|
|
57
|
-
})
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
22
|
}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
import { FirebaseFunction
|
|
2
|
-
import { Configuration, Fine,
|
|
1
|
+
import { FirebaseFunction } from '@stevenkellner/firebase-function';
|
|
2
|
+
import { Configuration, Fine, Person, Team } from '../../types';
|
|
3
3
|
import { Flattable, ObjectTypeBuilder, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
4
|
-
import { checkAuthentication } from '../../checkAuthentication';
|
|
5
|
-
import { Firestore } from '../../Firestore';
|
|
6
|
-
import { pushNotification } from '../../pushNotification';
|
|
7
4
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
id: Fine.Id,
|
|
14
|
-
configuration: Configuration
|
|
15
|
-
}
|
|
5
|
+
export type FineDeleteFunctionParameters = {
|
|
6
|
+
teamId: Team.Id,
|
|
7
|
+
personId: Person.Id,
|
|
8
|
+
id: Fine.Id,
|
|
9
|
+
configuration: Configuration
|
|
16
10
|
}
|
|
17
11
|
|
|
18
|
-
export class
|
|
12
|
+
export abstract class FineDeleteFunctionBase extends FirebaseFunction<FineDeleteFunctionParameters, void> {
|
|
19
13
|
|
|
20
|
-
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<
|
|
14
|
+
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineDeleteFunctionParameters>, FineDeleteFunctionParameters>({
|
|
21
15
|
teamId: Team.Id.builder,
|
|
22
16
|
personId: Person.Id.builder,
|
|
23
17
|
id: Fine.Id.builder,
|
|
@@ -25,32 +19,4 @@ export class FineDeleteFunction extends FirebaseFunction<FineDeleteFunction.Para
|
|
|
25
19
|
});
|
|
26
20
|
|
|
27
21
|
public returnTypeBuilder = new ValueTypeBuilder<void>();
|
|
28
|
-
|
|
29
|
-
public async execute(parameters: FineDeleteFunction.Parameters): Promise<void> {
|
|
30
|
-
|
|
31
|
-
await checkAuthentication(this.userId, parameters.teamId, 'fine-manager');
|
|
32
|
-
|
|
33
|
-
const fineSnapshot = await Firestore.shared.fine(parameters.teamId, parameters.id).snapshot();
|
|
34
|
-
if (!fineSnapshot.exists)
|
|
35
|
-
throw new FunctionsError('not-found', 'Fine not found');
|
|
36
|
-
|
|
37
|
-
const personSnapshot = await Firestore.shared.person(parameters.teamId, parameters.personId).snapshot();
|
|
38
|
-
if (!personSnapshot.exists)
|
|
39
|
-
throw new FunctionsError('not-found', 'Person not found');
|
|
40
|
-
const person = Person.builder.build(personSnapshot.data);
|
|
41
|
-
|
|
42
|
-
await Firestore.shared.fine(parameters.teamId, parameters.id).remove();
|
|
43
|
-
|
|
44
|
-
person.fineIds = person.fineIds.filter(id => id.guidString !== parameters.id.guidString);
|
|
45
|
-
await Firestore.shared.person(parameters.teamId, parameters.personId).set(person);
|
|
46
|
-
|
|
47
|
-
Localization.locale = parameters.configuration.locale;
|
|
48
|
-
await pushNotification(parameters.teamId, parameters.personId, 'fine-state-change', {
|
|
49
|
-
title: Localization.shared.notification.fine.stateChange.title.value(),
|
|
50
|
-
body: Localization.shared.notification.fine.stateChange.bodyDeleted.value({
|
|
51
|
-
amount: FineAmount.builder.build(fineSnapshot.data.amount).formatted(parameters.configuration),
|
|
52
|
-
reason: fineSnapshot.data.reason
|
|
53
|
-
})
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
22
|
}
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
import { Configuration } from '../../types/Configuration';
|
|
2
|
-
import { FirebaseFunction
|
|
3
|
-
import {
|
|
4
|
-
import { Fine, Localization, Person, Team, ValueLocalization } from '../../types';
|
|
2
|
+
import { FirebaseFunction } from '@stevenkellner/firebase-function';
|
|
3
|
+
import { Fine, Person, Team } from '../../types';
|
|
5
4
|
import { Flattable, ObjectTypeBuilder, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
6
|
-
import { checkAuthentication } from '../../checkAuthentication';
|
|
7
|
-
import { Firestore } from '../../Firestore';
|
|
8
5
|
|
|
9
|
-
export
|
|
6
|
+
export type FineUpdateFunctionParameters = {
|
|
7
|
+
teamId: Team.Id,
|
|
8
|
+
personId: Person.Id,
|
|
9
|
+
fine: Fine,
|
|
10
|
+
configuration: Configuration
|
|
11
|
+
};
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
teamId: Team.Id,
|
|
13
|
-
personId: Person.Id,
|
|
14
|
-
fine: Fine,
|
|
15
|
-
configuration: Configuration
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class FineUpdateFunction extends FirebaseFunction<FineUpdateFunction.Parameters, void> {
|
|
13
|
+
export abstract class FineUpdateFunctionBase extends FirebaseFunction<FineUpdateFunctionParameters, void> {
|
|
20
14
|
|
|
21
|
-
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<
|
|
15
|
+
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineUpdateFunctionParameters>, FineUpdateFunctionParameters>({
|
|
22
16
|
teamId: Team.Id.builder,
|
|
23
17
|
personId: Person.Id.builder,
|
|
24
18
|
fine: Fine.builder,
|
|
@@ -26,32 +20,4 @@ export class FineUpdateFunction extends FirebaseFunction<FineUpdateFunction.Para
|
|
|
26
20
|
});
|
|
27
21
|
|
|
28
22
|
public returnTypeBuilder = new ValueTypeBuilder<void>();
|
|
29
|
-
|
|
30
|
-
public async execute(parameters: FineUpdateFunction.Parameters): Promise<void> {
|
|
31
|
-
|
|
32
|
-
await checkAuthentication(this.userId, parameters.teamId, 'fine-manager');
|
|
33
|
-
|
|
34
|
-
const fineSnapshot = await Firestore.shared.fine(parameters.teamId, parameters.fine.id).snapshot();
|
|
35
|
-
if (!fineSnapshot.exists)
|
|
36
|
-
throw new FunctionsError('not-found', 'Fine not found');
|
|
37
|
-
|
|
38
|
-
await Firestore.shared.fine(parameters.teamId, parameters.fine.id).set(parameters.fine);
|
|
39
|
-
|
|
40
|
-
Localization.locale = parameters.configuration.locale;
|
|
41
|
-
if (parameters.fine.payedState !== fineSnapshot.data.payedState) {
|
|
42
|
-
let bodyLocalization: ValueLocalization;
|
|
43
|
-
if (parameters.fine.payedState === 'payed')
|
|
44
|
-
bodyLocalization = Localization.shared.notification.fine.stateChange.bodyPayed;
|
|
45
|
-
else
|
|
46
|
-
bodyLocalization = Localization.shared.notification.fine.stateChange.bodyUnpayed;
|
|
47
|
-
await pushNotification(parameters.teamId, parameters.personId, 'fine-state-change', {
|
|
48
|
-
title: Localization.shared.notification.fine.stateChange.title.value(),
|
|
49
|
-
body: bodyLocalization.value({
|
|
50
|
-
reason: parameters.fine.reason,
|
|
51
|
-
amount: parameters.fine.amount.formatted(parameters.configuration)
|
|
52
|
-
})
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
23
|
}
|
|
@@ -1,34 +1,18 @@
|
|
|
1
|
-
import { FirebaseFunction
|
|
1
|
+
import { FirebaseFunction } from '@stevenkellner/firebase-function';
|
|
2
2
|
import { FineTemplate, Team } from '../../types';
|
|
3
3
|
import { Flattable, ObjectTypeBuilder, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
4
|
-
import { checkAuthentication } from '../../checkAuthentication';
|
|
5
|
-
import { Firestore } from '../../Firestore';
|
|
6
4
|
|
|
7
|
-
export
|
|
5
|
+
export type FineTemplateAddFunctionParameters = {
|
|
6
|
+
teamId: Team.Id,
|
|
7
|
+
fineTemplate: FineTemplate
|
|
8
|
+
};
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
teamId: Team.Id,
|
|
11
|
-
fineTemplate: FineTemplate
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class FineTemplateAddFunction extends FirebaseFunction<FineTemplateAddFunction.Parameters, void> {
|
|
10
|
+
export abstract class FineTemplateAddFunctionBase extends FirebaseFunction<FineTemplateAddFunctionParameters, void> {
|
|
16
11
|
|
|
17
|
-
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<
|
|
12
|
+
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineTemplateAddFunctionParameters>, FineTemplateAddFunctionParameters>({
|
|
18
13
|
teamId: Team.Id.builder,
|
|
19
14
|
fineTemplate: FineTemplate.builder
|
|
20
15
|
});
|
|
21
16
|
|
|
22
17
|
public returnTypeBuilder = new ValueTypeBuilder<void>();
|
|
23
|
-
|
|
24
|
-
public async execute(parameters: FineTemplateAddFunction.Parameters): Promise<void> {
|
|
25
|
-
|
|
26
|
-
await checkAuthentication(this.userId, parameters.teamId, 'fineTemplate-manager');
|
|
27
|
-
|
|
28
|
-
const fineTemplateSnapshot = await Firestore.shared.fineTemplate(parameters.teamId, parameters.fineTemplate.id).snapshot();
|
|
29
|
-
if (fineTemplateSnapshot.exists)
|
|
30
|
-
throw new FunctionsError('already-exists', 'FineTemplate already exists');
|
|
31
|
-
|
|
32
|
-
await Firestore.shared.fineTemplate(parameters.teamId, parameters.fineTemplate.id).set(parameters.fineTemplate);
|
|
33
|
-
}
|
|
34
18
|
}
|
|
@@ -1,34 +1,18 @@
|
|
|
1
|
-
import { FirebaseFunction
|
|
1
|
+
import { FirebaseFunction } from '@stevenkellner/firebase-function';
|
|
2
2
|
import { FineTemplate, Team } from '../../types';
|
|
3
3
|
import { Flattable, ObjectTypeBuilder, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
4
|
-
import { checkAuthentication } from '../../checkAuthentication';
|
|
5
|
-
import { Firestore } from '../../Firestore';
|
|
6
4
|
|
|
7
|
-
export
|
|
5
|
+
export type FineTemplateDeleteFunctionParameters = {
|
|
6
|
+
teamId: Team.Id,
|
|
7
|
+
id: FineTemplate.Id
|
|
8
|
+
};
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
teamId: Team.Id,
|
|
11
|
-
id: FineTemplate.Id
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class FineTemplateDeleteFunction extends FirebaseFunction<FineTemplateDeleteFunction.Parameters, void> {
|
|
10
|
+
export abstract class FineTemplateDeleteFunctionBase extends FirebaseFunction<FineTemplateDeleteFunctionParameters, void> {
|
|
16
11
|
|
|
17
|
-
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<
|
|
12
|
+
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineTemplateDeleteFunctionParameters>, FineTemplateDeleteFunctionParameters>({
|
|
18
13
|
teamId: Team.Id.builder,
|
|
19
14
|
id: FineTemplate.Id.builder
|
|
20
15
|
});
|
|
21
16
|
|
|
22
17
|
public returnTypeBuilder = new ValueTypeBuilder<void>();
|
|
23
|
-
|
|
24
|
-
public async execute(parameters: FineTemplateDeleteFunction.Parameters): Promise<void> {
|
|
25
|
-
|
|
26
|
-
await checkAuthentication(this.userId, parameters.teamId, 'fineTemplate-manager');
|
|
27
|
-
|
|
28
|
-
const fineTemplateSnapshot = await Firestore.shared.fineTemplate(parameters.teamId, parameters.id).snapshot();
|
|
29
|
-
if (!fineTemplateSnapshot.exists)
|
|
30
|
-
throw new FunctionsError('not-found', 'FineTemplate not found');
|
|
31
|
-
|
|
32
|
-
await Firestore.shared.fineTemplate(parameters.teamId, parameters.id).remove();
|
|
33
|
-
}
|
|
34
18
|
}
|
|
@@ -1,34 +1,17 @@
|
|
|
1
|
-
import { FirebaseFunction
|
|
1
|
+
import { FirebaseFunction } from '@stevenkellner/firebase-function';
|
|
2
2
|
import { FineTemplate, Team } from '../../types';
|
|
3
3
|
import { Flattable, ObjectTypeBuilder, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
4
|
-
import { checkAuthentication } from '../../checkAuthentication';
|
|
5
|
-
import { Firestore } from '../../Firestore';
|
|
6
4
|
|
|
7
|
-
export
|
|
5
|
+
export type FineTemplateUpdateFunctionParameters = {
|
|
6
|
+
teamId: Team.Id,
|
|
7
|
+
fineTemplate: FineTemplate
|
|
8
|
+
};
|
|
9
|
+
export abstract class FineTemplateUpdateFunctionBase extends FirebaseFunction<FineTemplateUpdateFunctionParameters, void> {
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
teamId: Team.Id,
|
|
11
|
-
fineTemplate: FineTemplate
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class FineTemplateUpdateFunction extends FirebaseFunction<FineTemplateUpdateFunction.Parameters, void> {
|
|
16
|
-
|
|
17
|
-
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineTemplateUpdateFunction.Parameters>, FineTemplateUpdateFunction.Parameters>({
|
|
11
|
+
public parametersBuilder = new ObjectTypeBuilder<Flattable.Flatten<FineTemplateUpdateFunctionParameters>, FineTemplateUpdateFunctionParameters>({
|
|
18
12
|
teamId: Team.Id.builder,
|
|
19
13
|
fineTemplate: FineTemplate.builder
|
|
20
14
|
});
|
|
21
15
|
|
|
22
16
|
public returnTypeBuilder = new ValueTypeBuilder<void>();
|
|
23
|
-
|
|
24
|
-
public async execute(parameters: FineTemplateUpdateFunction.Parameters): Promise<void> {
|
|
25
|
-
|
|
26
|
-
await checkAuthentication(this.userId, parameters.teamId, 'fineTemplate-manager');
|
|
27
|
-
|
|
28
|
-
const fineTemplateSnapshot = await Firestore.shared.fineTemplate(parameters.teamId, parameters.fineTemplate.id).snapshot();
|
|
29
|
-
if (!fineTemplateSnapshot.exists)
|
|
30
|
-
throw new FunctionsError('not-found', 'FineTemplate not found');
|
|
31
|
-
|
|
32
|
-
await Firestore.shared.fineTemplate(parameters.teamId, parameters.fineTemplate.id).set(parameters.fineTemplate);
|
|
33
|
-
}
|
|
34
17
|
}
|
package/src/functions/index.ts
CHANGED