@nacre.work/core 0.34.0 → 0.35.0
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/dist/audit-actions.d.ts.map +1 -1
- package/dist/audit-actions.js +5 -1
- package/dist/audit-actions.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mail.d.ts.map +1 -1
- package/dist/mail.js +13 -4
- package/dist/mail.js.map +1 -1
- package/dist/migrations/0040_notifications.sql +139 -0
- package/dist/notifications.d.ts +134 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +172 -0
- package/dist/notifications.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { type Message } from './mail.js';
|
|
2
|
+
/**
|
|
3
|
+
* Notifications and alert rules. docs/mcp-admin.md, "Notifications".
|
|
4
|
+
*
|
|
5
|
+
* The bounds, the one validation both ends run, and the two messages the
|
|
6
|
+
* worker sends. In the core rather than beside the API's other messages
|
|
7
|
+
* because the worker sends these and cannot import the API — and
|
|
8
|
+
* `packages/api/src/messages.ts` lists them with the rest, so the preview and
|
|
9
|
+
* anything else reasoning about the set still sees one list.
|
|
10
|
+
*
|
|
11
|
+
* ## Who can receive one
|
|
12
|
+
*
|
|
13
|
+
* A recipient is a **user id** in the caller's own organization, active, and
|
|
14
|
+
* nothing else. There is no field for an address anywhere: the tools take an
|
|
15
|
+
* address only to *find a person*, the outbox stores ids, and the worker reads
|
|
16
|
+
* the address from `users` at the moment of sending, scoped to the
|
|
17
|
+
* notification's organization. T35 is the refusal at the first step; the
|
|
18
|
+
* second and third are why the first is not the only thing standing.
|
|
19
|
+
*
|
|
20
|
+
* ## Why a notification carries no links
|
|
21
|
+
*
|
|
22
|
+
* The body is somebody's prose sent from this installation's own address, to
|
|
23
|
+
* everybody in an organization if the agent asked for that — which is the
|
|
24
|
+
* exact shape of a phishing message, and on a surface whose threat model is an
|
|
25
|
+
* instruction planted in a document. A person applies every one, and reads it
|
|
26
|
+
* first; a person also reads a message saying their password expired and
|
|
27
|
+
* linking somewhere convincing. So a URL in either part is refused, with the
|
|
28
|
+
* reason, and the only link in a message this installation sends is one the
|
|
29
|
+
* installation built from its own configuration.
|
|
30
|
+
*/
|
|
31
|
+
/** Explicit recipients on one notification or one rule. "Every org_admin" is a flag, not a list. */
|
|
32
|
+
export declare const NOTIFY_MAX_RECIPIENTS = 20;
|
|
33
|
+
export declare const NOTIFY_SUBJECT_MAX = 200;
|
|
34
|
+
export declare const NOTIFY_BODY_MAX = 4000;
|
|
35
|
+
/**
|
|
36
|
+
* Notifications queued per organization in any hour, agents and rules together.
|
|
37
|
+
*
|
|
38
|
+
* A constant rather than a variable: it is the bound on how loud one tenant's
|
|
39
|
+
* agent can be through the installation's relay, and an operator who wants a
|
|
40
|
+
* louder one is asking for something nobody has argued for. Thirty is a
|
|
41
|
+
* person's inbox having a bad hour, not a mailing list.
|
|
42
|
+
*/
|
|
43
|
+
export declare const NOTIFY_PER_HOUR = 30;
|
|
44
|
+
/** What an alert rule can watch. Each is answered from what the database already records. */
|
|
45
|
+
export declare const ALERT_KINDS: {
|
|
46
|
+
readonly skill_by_agent: {
|
|
47
|
+
readonly counts: false;
|
|
48
|
+
readonly layered: true;
|
|
49
|
+
readonly summary: "a skill version written by an agent";
|
|
50
|
+
};
|
|
51
|
+
readonly skill_scripts: {
|
|
52
|
+
readonly counts: false;
|
|
53
|
+
readonly layered: true;
|
|
54
|
+
readonly summary: "a skill version that adds scripts";
|
|
55
|
+
};
|
|
56
|
+
readonly admin_connection: {
|
|
57
|
+
readonly counts: false;
|
|
58
|
+
readonly layered: false;
|
|
59
|
+
readonly summary: "an administrative connection approved";
|
|
60
|
+
};
|
|
61
|
+
readonly denial_spike: {
|
|
62
|
+
readonly counts: true;
|
|
63
|
+
readonly layered: false;
|
|
64
|
+
readonly summary: "one person or service account denied at least the threshold within the window";
|
|
65
|
+
};
|
|
66
|
+
readonly documents_failed: {
|
|
67
|
+
readonly counts: true;
|
|
68
|
+
readonly layered: true;
|
|
69
|
+
readonly summary: "at least the threshold of documents failing to index within the window";
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
export type AlertKind = keyof typeof ALERT_KINDS;
|
|
73
|
+
export declare const isAlertKind: (value: unknown) => value is AlertKind;
|
|
74
|
+
/** The window a counting rule takes, in minutes. */
|
|
75
|
+
export declare const ALERT_WINDOW: {
|
|
76
|
+
readonly min: 5;
|
|
77
|
+
readonly max: 1440;
|
|
78
|
+
readonly default: 60;
|
|
79
|
+
};
|
|
80
|
+
/** The sentence a rule is read as, from what it stores. */
|
|
81
|
+
export declare function ruleSentence(rule: {
|
|
82
|
+
readonly kind: AlertKind;
|
|
83
|
+
readonly layerSlug: string | null;
|
|
84
|
+
readonly threshold: number | null;
|
|
85
|
+
readonly windowMinutes: number | null;
|
|
86
|
+
}): string;
|
|
87
|
+
/**
|
|
88
|
+
* A subject and a body, or the sentence saying why not.
|
|
89
|
+
*
|
|
90
|
+
* Both ends ask it: the tool when it proposes, so the person is never shown
|
|
91
|
+
* something that would be refused, and the apply, because a stored proposal is
|
|
92
|
+
* not trusted for having been checked ten minutes ago.
|
|
93
|
+
*/
|
|
94
|
+
export declare function notificationText(subject: unknown, body: unknown): {
|
|
95
|
+
readonly subject: string;
|
|
96
|
+
readonly body: string;
|
|
97
|
+
} | {
|
|
98
|
+
readonly refused: string;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* A name somebody outside the organization chose — an application's registered
|
|
102
|
+
* name — made safe to put in a message's text: one line, bounded, and broken
|
|
103
|
+
* where a mail client would otherwise turn it into a link. The rule above, for
|
|
104
|
+
* the one string in an alert that this installation did not write.
|
|
105
|
+
*/
|
|
106
|
+
export declare function plainName(value: string): string;
|
|
107
|
+
/** What a stored notification says about where it came from, for the message's last line. */
|
|
108
|
+
export type NotificationOrigin = {
|
|
109
|
+
readonly source: 'agent';
|
|
110
|
+
/** The person who applied it. */
|
|
111
|
+
readonly appliedBy: string;
|
|
112
|
+
/** The application the administrative connection was approved for. */
|
|
113
|
+
readonly application: string;
|
|
114
|
+
} | {
|
|
115
|
+
readonly source: 'rule';
|
|
116
|
+
/** What the rule watches, as `ruleSentence` says it. */
|
|
117
|
+
readonly when: string;
|
|
118
|
+
/** Who created the rule, by address, or null where they are gone. */
|
|
119
|
+
readonly ruleBy: string | null;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* A notification, in the brand, to one address.
|
|
123
|
+
*
|
|
124
|
+
* The body is the stored text, a paragraph per blank-line-separated block. The
|
|
125
|
+
* last line says where it came from — an agent, through which application, and
|
|
126
|
+
* who applied it; or which rule — because a message from this installation's
|
|
127
|
+
* address that an agent wrote has to say so, or it borrows trust it was not
|
|
128
|
+
* given. The one link is to the access log, built from configuration.
|
|
129
|
+
*/
|
|
130
|
+
export declare function notificationMessage(to: string, consoleBase: string, stored: {
|
|
131
|
+
readonly subject: string;
|
|
132
|
+
readonly body: string;
|
|
133
|
+
}, origin: NotificationOrigin): Message;
|
|
134
|
+
//# sourceMappingURL=notifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../notifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,oGAAoG;AACpG,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAEvC,eAAO,MAAM,kBAAkB,MAAM,CAAA;AACrC,eAAO,MAAM,eAAe,OAAO,CAAA;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,KAAK,CAAA;AAEjC,6FAA6F;AAC7F,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Bd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAA;AAEhD,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,SACiC,CAAA;AAEvF,oDAAoD;AACpD,eAAO,MAAM,YAAY;;;;CAA8C,CAAA;AAEvE,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CACtC,GAAG,MAAM,CAcT;AAWD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,GACZ;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAqBpF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,6FAA6F;AAC7F,MAAM,MAAM,kBAAkB,GAC1B;IACE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,iCAAiC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B,CAAA;AAEL;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC3D,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAmBT"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { consoleUrl, message } from './mail.js';
|
|
2
|
+
/**
|
|
3
|
+
* Notifications and alert rules. docs/mcp-admin.md, "Notifications".
|
|
4
|
+
*
|
|
5
|
+
* The bounds, the one validation both ends run, and the two messages the
|
|
6
|
+
* worker sends. In the core rather than beside the API's other messages
|
|
7
|
+
* because the worker sends these and cannot import the API — and
|
|
8
|
+
* `packages/api/src/messages.ts` lists them with the rest, so the preview and
|
|
9
|
+
* anything else reasoning about the set still sees one list.
|
|
10
|
+
*
|
|
11
|
+
* ## Who can receive one
|
|
12
|
+
*
|
|
13
|
+
* A recipient is a **user id** in the caller's own organization, active, and
|
|
14
|
+
* nothing else. There is no field for an address anywhere: the tools take an
|
|
15
|
+
* address only to *find a person*, the outbox stores ids, and the worker reads
|
|
16
|
+
* the address from `users` at the moment of sending, scoped to the
|
|
17
|
+
* notification's organization. T35 is the refusal at the first step; the
|
|
18
|
+
* second and third are why the first is not the only thing standing.
|
|
19
|
+
*
|
|
20
|
+
* ## Why a notification carries no links
|
|
21
|
+
*
|
|
22
|
+
* The body is somebody's prose sent from this installation's own address, to
|
|
23
|
+
* everybody in an organization if the agent asked for that — which is the
|
|
24
|
+
* exact shape of a phishing message, and on a surface whose threat model is an
|
|
25
|
+
* instruction planted in a document. A person applies every one, and reads it
|
|
26
|
+
* first; a person also reads a message saying their password expired and
|
|
27
|
+
* linking somewhere convincing. So a URL in either part is refused, with the
|
|
28
|
+
* reason, and the only link in a message this installation sends is one the
|
|
29
|
+
* installation built from its own configuration.
|
|
30
|
+
*/
|
|
31
|
+
/** Explicit recipients on one notification or one rule. "Every org_admin" is a flag, not a list. */
|
|
32
|
+
export const NOTIFY_MAX_RECIPIENTS = 20;
|
|
33
|
+
export const NOTIFY_SUBJECT_MAX = 200;
|
|
34
|
+
export const NOTIFY_BODY_MAX = 4000;
|
|
35
|
+
/**
|
|
36
|
+
* Notifications queued per organization in any hour, agents and rules together.
|
|
37
|
+
*
|
|
38
|
+
* A constant rather than a variable: it is the bound on how loud one tenant's
|
|
39
|
+
* agent can be through the installation's relay, and an operator who wants a
|
|
40
|
+
* louder one is asking for something nobody has argued for. Thirty is a
|
|
41
|
+
* person's inbox having a bad hour, not a mailing list.
|
|
42
|
+
*/
|
|
43
|
+
export const NOTIFY_PER_HOUR = 30;
|
|
44
|
+
/** What an alert rule can watch. Each is answered from what the database already records. */
|
|
45
|
+
export const ALERT_KINDS = {
|
|
46
|
+
skill_by_agent: {
|
|
47
|
+
counts: false,
|
|
48
|
+
layered: true,
|
|
49
|
+
summary: 'a skill version written by an agent',
|
|
50
|
+
},
|
|
51
|
+
skill_scripts: {
|
|
52
|
+
counts: false,
|
|
53
|
+
layered: true,
|
|
54
|
+
summary: 'a skill version that adds scripts',
|
|
55
|
+
},
|
|
56
|
+
admin_connection: {
|
|
57
|
+
counts: false,
|
|
58
|
+
layered: false,
|
|
59
|
+
summary: 'an administrative connection approved',
|
|
60
|
+
},
|
|
61
|
+
denial_spike: {
|
|
62
|
+
counts: true,
|
|
63
|
+
layered: false,
|
|
64
|
+
summary: 'one person or service account denied at least the threshold within the window',
|
|
65
|
+
},
|
|
66
|
+
documents_failed: {
|
|
67
|
+
counts: true,
|
|
68
|
+
layered: true,
|
|
69
|
+
summary: 'at least the threshold of documents failing to index within the window',
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
export const isAlertKind = (value) => typeof value === 'string' && Object.prototype.hasOwnProperty.call(ALERT_KINDS, value);
|
|
73
|
+
/** The window a counting rule takes, in minutes. */
|
|
74
|
+
export const ALERT_WINDOW = { min: 5, max: 1440, default: 60 };
|
|
75
|
+
/** The sentence a rule is read as, from what it stores. */
|
|
76
|
+
export function ruleSentence(rule) {
|
|
77
|
+
const where = rule.layerSlug === null ? '' : ` in the layer ${rule.layerSlug}`;
|
|
78
|
+
switch (rule.kind) {
|
|
79
|
+
case 'skill_by_agent':
|
|
80
|
+
return `an agent writes a skill version${where === '' ? '' : where.replace(' in ', ' for ')}`;
|
|
81
|
+
case 'skill_scripts':
|
|
82
|
+
return `a skill version adds scripts${where === '' ? '' : where.replace(' in ', ' for ')}`;
|
|
83
|
+
case 'admin_connection':
|
|
84
|
+
return 'somebody approves an administrative connection';
|
|
85
|
+
case 'denial_spike':
|
|
86
|
+
return `one person or service account is denied ${String(rule.threshold)} or more times within ${String(rule.windowMinutes)} minutes`;
|
|
87
|
+
case 'documents_failed':
|
|
88
|
+
return `${String(rule.threshold)} or more documents fail to index within ${String(rule.windowMinutes)} minutes${where}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A URL, or something a mail client would turn into one: a scheme, `www.`, or
|
|
93
|
+
* a dotted name followed by a path. A bare `example.com` is not refused,
|
|
94
|
+
* because `contract.pdf` is the same shape and over-refusing prose is how a
|
|
95
|
+
* check gets worked around; with no scheme and no path it is the weakest of
|
|
96
|
+
* the three, and the person reads the message before it goes.
|
|
97
|
+
*/
|
|
98
|
+
const LINKISH = /\b(?:https?|ftp|mailto|javascript|data|file):|\bwww\.[a-z0-9-]+\.|\b[a-z0-9-]+(?:\.[a-z0-9-]+)+\//iu;
|
|
99
|
+
/**
|
|
100
|
+
* A subject and a body, or the sentence saying why not.
|
|
101
|
+
*
|
|
102
|
+
* Both ends ask it: the tool when it proposes, so the person is never shown
|
|
103
|
+
* something that would be refused, and the apply, because a stored proposal is
|
|
104
|
+
* not trusted for having been checked ten minutes ago.
|
|
105
|
+
*/
|
|
106
|
+
export function notificationText(subject, body) {
|
|
107
|
+
if (typeof subject !== 'string' || subject.trim() === '')
|
|
108
|
+
return { refused: "'subject' is required." };
|
|
109
|
+
if (typeof body !== 'string' || body.trim() === '')
|
|
110
|
+
return { refused: "'body' is required." };
|
|
111
|
+
const s = subject.trim();
|
|
112
|
+
// Line endings normalised before the length and character checks, so a body
|
|
113
|
+
// written on Windows is not refused for the carriage returns in it.
|
|
114
|
+
const b = body.replace(/\r\n?/gu, '\n').trim();
|
|
115
|
+
if (s.length > NOTIFY_SUBJECT_MAX)
|
|
116
|
+
return { refused: `The subject is at most ${String(NOTIFY_SUBJECT_MAX)} characters.` };
|
|
117
|
+
if (b.length > NOTIFY_BODY_MAX)
|
|
118
|
+
return { refused: `The body is at most ${String(NOTIFY_BODY_MAX)} characters.` };
|
|
119
|
+
// eslint-disable-next-line no-control-regex -- refusing control characters is the point
|
|
120
|
+
if (/[\u0000-\u001f\u007f]/u.test(s))
|
|
121
|
+
return { refused: 'The subject is one line of plain text.' };
|
|
122
|
+
// eslint-disable-next-line no-control-regex -- the same, with newline and tab allowed
|
|
123
|
+
if (/[\u0000-\u0008\u000b-\u001f\u007f]/u.test(b))
|
|
124
|
+
return { refused: 'The body is plain text: no control characters.' };
|
|
125
|
+
if (LINKISH.test(s) || LINKISH.test(b)) {
|
|
126
|
+
return {
|
|
127
|
+
refused: 'A notification carries no links. It is sent from this installation\'s own address, so a link in it is ' +
|
|
128
|
+
'one people have every reason to trust — name the layer, document or screen instead.',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return { subject: s, body: b };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A name somebody outside the organization chose — an application's registered
|
|
135
|
+
* name — made safe to put in a message's text: one line, bounded, and broken
|
|
136
|
+
* where a mail client would otherwise turn it into a link. The rule above, for
|
|
137
|
+
* the one string in an alert that this installation did not write.
|
|
138
|
+
*/
|
|
139
|
+
export function plainName(value) {
|
|
140
|
+
// eslint-disable-next-line no-control-regex -- control characters are what is being removed
|
|
141
|
+
const line = value.replace(/[\u0000-\u001f\u007f]+/gu, ' ').replace(/\s+/gu, ' ').trim().slice(0, 80);
|
|
142
|
+
return LINKISH.test(line) ? line.replace(/([.:/@])/gu, '$1 ').replace(/\s+/gu, ' ').trim() : line;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A notification, in the brand, to one address.
|
|
146
|
+
*
|
|
147
|
+
* The body is the stored text, a paragraph per blank-line-separated block. The
|
|
148
|
+
* last line says where it came from — an agent, through which application, and
|
|
149
|
+
* who applied it; or which rule — because a message from this installation's
|
|
150
|
+
* address that an agent wrote has to say so, or it borrows trust it was not
|
|
151
|
+
* given. The one link is to the access log, built from configuration.
|
|
152
|
+
*/
|
|
153
|
+
export function notificationMessage(to, consoleBase, stored, origin) {
|
|
154
|
+
const paragraphs = stored.body
|
|
155
|
+
.split(/\n\s*\n/u)
|
|
156
|
+
.map((p) => p.trim())
|
|
157
|
+
.filter((p) => p !== '')
|
|
158
|
+
.map((text) => ({ kind: 'say', text }));
|
|
159
|
+
const provenance = origin.source === 'agent'
|
|
160
|
+
? `An agent wrote this through the administrative connection of the application "${origin.application}", and ${origin.appliedBy} ` +
|
|
161
|
+
'read it and approved sending it. Nobody outside your organization can be sent one.'
|
|
162
|
+
: `An alert rule your organization keeps sent this: it emails whenever ${origin.when}` +
|
|
163
|
+
`${origin.ruleBy === null ? '' : `, and ${origin.ruleBy} set it up`}. An administrator can remove it.`;
|
|
164
|
+
// Prefixed both ways, so the subject line alone says this is the
|
|
165
|
+
// installation speaking and which kind of message it is.
|
|
166
|
+
return message(to, `${origin.source === 'rule' ? 'Nacre alert' : 'Nacre'}: ${stored.subject}`, [
|
|
167
|
+
...paragraphs,
|
|
168
|
+
{ kind: 'link', url: consoleUrl(consoleBase, '#/audit'), label: 'Open the access log' },
|
|
169
|
+
{ kind: 'caution', text: provenance },
|
|
170
|
+
]);
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../notifications.ts"],"names":[],"mappings":"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"}
|