Skip to content

Commit 634913b

Browse files
FEATURE (docs): Update contribution docs
1 parent 12ffe5d commit 634913b

File tree

2 files changed

+141
-25
lines changed

2 files changed

+141
-25
lines changed

app/contribute/how-to-add-notifier/page.tsx

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export default function HowToAddNotifierPage() {
8686
and build the frontend UI components.
8787
</p>
8888

89-
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4 my-6">
89+
<div className="rounded-lg border border-blue-200 bg-blue-50 pt-4 px-4 my-6">
9090
<p className="text-sm text-blue-900 m-0">
9191
<strong>💡 Note:</strong> This is a contribution guide for
9292
developers who want to add new notification integrations to
@@ -118,26 +118,49 @@ export default function HowToAddNotifierPage() {
118118
folder.
119119
</p>
120120

121-
<p>The interface requires three methods:</p>
121+
<p>The interface requires the following methods:</p>
122122

123123
<ul>
124124
<li>
125125
<code>
126-
Send(logger *slog.Logger, heading string, message string)
127-
error
126+
Send(encryptor encryption.FieldEncryptor, logger
127+
*slog.Logger, heading string, message string) error
128128
</code>{" "}
129129
- sends the notification
130130
</li>
131131
<li>
132-
<code>Validate() error</code> - validates the configuration
132+
<code>
133+
Validate(encryptor encryption.FieldEncryptor) error
134+
</code>{" "}
135+
- validates the configuration
133136
</li>
134137
<li>
135138
<code>HideSensitiveData()</code> - masks sensitive fields
136139
before logging/display
137140
</li>
141+
<li>
142+
<code>
143+
EncryptSensitiveData(encryptor encryption.FieldEncryptor)
144+
error
145+
</code>{" "}
146+
- encrypts sensitive fields before saving
147+
</li>
138148
</ul>
139149

140-
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4 my-6">
150+
<div className="rounded-lg border border-blue-200 bg-blue-50 pt-4 px-4 my-6">
151+
<p className="text-sm text-blue-900 m-0">
152+
<strong>🔐 Encryption requirement:</strong> All sensitive
153+
fields (bot tokens, webhook URLs, API keys, passwords) must be
154+
encrypted using the <code>EncryptSensitiveData()</code> method
155+
before saving to the database. Decrypt credentials in the{" "}
156+
<code>Send()</code> method before sending notifications. See{" "}
157+
<code>discord</code>, <code>telegram</code>,{" "}
158+
<code>slack</code>, or <code>teams</code> notifier models for
159+
implementation examples.
160+
</p>
161+
</div>
162+
163+
<div className="rounded-lg border border-gray-200 bg-gray-50 pt-4 px-4 my-6">
141164
<p className="text-sm text-gray-700 m-0">
142165
<strong>🔑 Important:</strong> Use UUID primary key as{" "}
143166
<code>NotifierID</code> that references the main notifiers
@@ -235,7 +258,7 @@ export default function HowToAddNotifierPage() {
235258
</li>
236259
</ul>
237260

238-
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4 my-6">
261+
<div className="rounded-lg border border-gray-200 bg-gray-50 pt-4 px-4 my-6">
239262
<p className="text-sm text-gray-700 m-0">
240263
<strong>💡 Tip:</strong> The <code>CASCADE DELETE</code>{" "}
241264
ensures that when a notifier is deleted from the main
@@ -244,12 +267,43 @@ export default function HowToAddNotifierPage() {
244267
</p>
245268
</div>
246269

247-
<h3 id="step-8-run-tests">8. Run tests</h3>
270+
<h3 id="step-8-run-tests">8. Update and run tests</h3>
271+
272+
<p>
273+
Update{" "}
274+
<code>
275+
backend/internal/features/notifiers/controller_test.go
276+
</code>{" "}
277+
to add encryption verification tests for your notifier:
278+
</p>
279+
280+
<ul>
281+
<li>
282+
Add a test case to{" "}
283+
<code>Test_NotifierSensitiveDataLifecycle_AllTypes</code> for
284+
your notifier type
285+
</li>
286+
<li>
287+
Add a test case to{" "}
288+
<code>
289+
Test_CreateNotifier_AllSensitiveFieldsEncryptedInDB
290+
</code>
291+
</li>
292+
<li>
293+
Verify that sensitive fields are encrypted with{" "}
294+
<code>enc:</code> prefix in the database
295+
</li>
296+
<li>
297+
Verify that decryption returns the original plaintext values
298+
</li>
299+
<li>
300+
Verify that sensitive data is hidden when retrieved via API
301+
</li>
302+
</ul>
248303

249304
<p>
250305
Before submitting your pull request, make sure all existing
251-
tests pass and consider adding new tests for your notifier
252-
implementation.
306+
tests pass and your new encryption tests are working correctly.
253307
</p>
254308

255309
<h2 id="frontend-implementation">Frontend implementation</h2>
@@ -259,7 +313,7 @@ export default function HowToAddNotifierPage() {
259313
validators and React components for managing your notifier.
260314
</p>
261315

262-
<div className="rounded-lg border border-amber-200 bg-amber-50 p-4 my-6">
316+
<div className="rounded-lg border border-amber-200 bg-amber-50 pt-4 px-4 my-6">
263317
<p className="text-sm text-amber-900 m-0">
264318
<strong>ℹ️ Backend-only contributions:</strong> If you&apos;re
265319
only comfortable with backend development, that&apos;s

app/contribute/how-to-add-storage/page.tsx

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default function HowToAddStoragePage() {
8787
build the frontend UI components for managing storage providers.
8888
</p>
8989

90-
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4 my-6">
90+
<div className="rounded-lg border border-blue-200 bg-blue-50 pt-4 px-4 my-6">
9191
<p className="text-sm text-blue-900 m-0">
9292
<strong>💡 Note:</strong> This is a contribution guide for
9393
developers who want to add new storage integrations to the
@@ -124,34 +124,63 @@ export default function HowToAddStoragePage() {
124124
<ul>
125125
<li>
126126
<code>
127-
SaveFile(logger *slog.Logger, fileID uuid.UUID, file
128-
io.Reader) error
127+
SaveFile(encryptor encryption.FieldEncryptor, logger
128+
*slog.Logger, fileID uuid.UUID, file io.Reader) error
129129
</code>{" "}
130130
- saves a backup file to the storage
131131
</li>
132132
<li>
133-
<code>GetFile(fileID uuid.UUID) (io.ReadCloser, error)</code>{" "}
133+
<code>
134+
GetFile(encryptor encryption.FieldEncryptor, fileID
135+
uuid.UUID) (io.ReadCloser, error)
136+
</code>{" "}
134137
- retrieves a backup file from the storage
135138
</li>
136139
<li>
137-
<code>DeleteFile(fileID uuid.UUID) error</code> - deletes a
138-
backup file from the storage
140+
<code>
141+
DeleteFile(encryptor encryption.FieldEncryptor, fileID
142+
uuid.UUID) error
143+
</code>{" "}
144+
- deletes a backup file from the storage
139145
</li>
140146
<li>
141-
<code>Validate() error</code> - validates the storage
142-
configuration
147+
<code>
148+
Validate(encryptor encryption.FieldEncryptor) error
149+
</code>{" "}
150+
- validates the storage configuration
143151
</li>
144152
<li>
145-
<code>TestConnection() error</code> - tests connectivity to
146-
the storage provider
153+
<code>
154+
TestConnection(encryptor encryption.FieldEncryptor) error
155+
</code>{" "}
156+
- tests connectivity to the storage provider
147157
</li>
148158
<li>
149159
<code>HideSensitiveData()</code> - masks sensitive fields like
150160
API keys before logging/display
151161
</li>
162+
<li>
163+
<code>
164+
EncryptSensitiveData(encryptor encryption.FieldEncryptor)
165+
error
166+
</code>{" "}
167+
- encrypts sensitive fields before saving
168+
</li>
152169
</ul>
153170

154-
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4 my-6">
171+
<div className="rounded-lg border border-blue-200 bg-blue-50 pt-4 px-4 my-6">
172+
<p className="text-sm text-blue-900 m-0">
173+
<strong>🔐 Encryption requirement:</strong> All sensitive
174+
fields (API keys, passwords, access tokens, secrets) must be
175+
encrypted using the <code>EncryptSensitiveData()</code> method
176+
before saving to the database. Decrypt credentials before
177+
using them. See <code>azure_blob</code>,{" "}
178+
<code>google_drive</code> or <code>s3</code> storage models
179+
for implementation examples.
180+
</p>
181+
</div>
182+
183+
<div className="rounded-lg border border-gray-200 bg-gray-50 pt-4 px-4 my-6">
155184
<p className="text-sm text-gray-700 m-0">
156185
<strong>🔑 Important:</strong> Use UUID primary key as{" "}
157186
<code>StorageID</code> that references the main storages
@@ -258,7 +287,7 @@ export default function HowToAddStoragePage() {
258287
</li>
259288
</ul>
260289

261-
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4 my-6">
290+
<div className="rounded-lg border border-gray-200 bg-gray-50 pt-4 px-4 my-6">
262291
<p className="text-sm text-gray-700 m-0">
263292
<strong>💡 Tip:</strong> The <code>CASCADE DELETE</code>{" "}
264293
ensures that when a storage is deleted from the main storages
@@ -282,6 +311,39 @@ export default function HowToAddStoragePage() {
282311
<li>Validation of configuration parameters</li>
283312
</ul>
284313

314+
<p>
315+
Additionally, update{" "}
316+
<code>
317+
backend/internal/features/storages/controller_test.go
318+
</code>{" "}
319+
to add encryption verification tests:
320+
</p>
321+
322+
<ul>
323+
<li>
324+
Add a test case to{" "}
325+
<code>Test_StorageSensitiveDataLifecycle_AllTypes</code> for
326+
your storage type
327+
</li>
328+
<li>
329+
Add a test case to{" "}
330+
<code>
331+
Test_CreateStorage_AllSensitiveFieldsEncryptedInDB
332+
</code>{" "}
333+
(if not already present)
334+
</li>
335+
<li>
336+
Verify that sensitive fields are encrypted with{" "}
337+
<code>enc:</code> prefix in the database
338+
</li>
339+
<li>
340+
Verify that decryption returns the original plaintext values
341+
</li>
342+
<li>
343+
Verify that sensitive data is hidden when retrieved via API
344+
</li>
345+
</ul>
346+
285347
<h3 id="step-9-run-tests">9. Run all tests</h3>
286348

287349
<p>
@@ -299,7 +361,7 @@ export default function HowToAddStoragePage() {
299361
provider.
300362
</p>
301363

302-
<div className="rounded-lg border border-amber-200 bg-amber-50 p-4 my-6">
364+
<div className="rounded-lg border border-amber-200 bg-amber-50 pt-4 px-4 my-6">
303365
<p className="text-sm text-amber-900 m-0">
304366
<strong>ℹ️ Backend-only contributions:</strong> If you&apos;re
305367
only comfortable with backend development, that&apos;s
@@ -466,7 +528,7 @@ export default function HowToAddStoragePage() {
466528
</li>
467529
</ol>
468530

469-
<div className="rounded-lg border border-green-200 bg-green-50 p-4 my-6">
531+
<div className="rounded-lg border border-green-200 bg-green-50 pt-4 px-4 my-6">
470532
<p className="text-sm text-green-900 m-0">
471533
<strong>🎉 Thank you!</strong> Your contributions help make
472534
Postgresus more versatile and valuable for the community. We

0 commit comments

Comments
 (0)