Initial commit
This commit is contained in:
21
pocketbase/pb_hooks/createOtpUser.pb.js
Normal file
21
pocketbase/pb_hooks/createOtpUser.pb.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/// <reference path="../pb_data/types.d.ts" />
|
||||
|
||||
onRecordRequestOTPRequest((e) => {
|
||||
// create a user with the OTP email if it doesn't exist
|
||||
|
||||
if (!e.record) {
|
||||
const email = e.requestInfo().body['email']
|
||||
const record = new Record(e.collection)
|
||||
record.setEmail(email)
|
||||
record.setPassword($security.randomString(30))
|
||||
|
||||
const language = e.requestInfo().headers['language'] || 'en'
|
||||
record.set('language', language)
|
||||
|
||||
e.app.save(record)
|
||||
|
||||
e.record = record
|
||||
}
|
||||
|
||||
return e.next()
|
||||
}, 'users')
|
||||
13
pocketbase/pb_hooks/locales/de.json
Normal file
13
pocketbase/pb_hooks/locales/de.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"mailSubject": {
|
||||
"authAlert": "Anmeldung von einem neuen Standort",
|
||||
"emailChange": "Bestätige deine neue {{.appName}}-E-Mail-Adresse",
|
||||
"otp": "Einmalpasswort für {{.appName}}",
|
||||
"passwortReset": "Setze dein {{.appName}}-Passwort zurück",
|
||||
"verification": "Bestätige deine {{.appName}}-E-Mail-Adresse"
|
||||
},
|
||||
"resetCounter": {
|
||||
"title": "Zähler zurückgesetzt",
|
||||
"body": "Ihr Zähler wurde auf null zurückgesetzt."
|
||||
}
|
||||
}
|
||||
13
pocketbase/pb_hooks/locales/en.json
Normal file
13
pocketbase/pb_hooks/locales/en.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"mailSubject": {
|
||||
"authAlert": "Login from a new location",
|
||||
"emailChange": "Confirm your {{.appName}} new email address",
|
||||
"otp": "OTP for {{.appName}}",
|
||||
"passwortReset": "Reset your {{.appName}} password",
|
||||
"verification": "Verify your {{.appName}} email"
|
||||
},
|
||||
"resetCounter": {
|
||||
"title": "Counter reset",
|
||||
"body": "Your counter has been reset to zero."
|
||||
}
|
||||
}
|
||||
26
pocketbase/pb_hooks/mailTemplates.pb.js
Normal file
26
pocketbase/pb_hooks/mailTemplates.pb.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/// <reference path="../pb_data/types.d.ts" />
|
||||
|
||||
onMailerRecordAuthAlertSend((e) => {
|
||||
const utils = require(`${__hooks}/utils/renderMailTemplate.js`)
|
||||
utils.renderMailTemplate(e, 'authAlert')
|
||||
})
|
||||
|
||||
onMailerRecordPasswordResetSend((e) => {
|
||||
const utils = require(`${__hooks}/utils/renderMailTemplate.js`)
|
||||
utils.renderMailTemplate(e, 'passwordReset')
|
||||
})
|
||||
|
||||
onMailerRecordVerificationSend((e) => {
|
||||
const utils = require(`${__hooks}/utils/renderMailTemplate.js`)
|
||||
utils.renderMailTemplate(e, 'verification')
|
||||
})
|
||||
|
||||
onMailerRecordEmailChangeSend((e) => {
|
||||
const utils = require(`${__hooks}/utils/renderMailTemplate.js`)
|
||||
utils.renderMailTemplate(e, 'emailChange')
|
||||
})
|
||||
|
||||
onMailerRecordOTPSend((e) => {
|
||||
const utils = require(`${__hooks}/utils/renderMailTemplate.js`)
|
||||
utils.renderMailTemplate(e, 'otp')
|
||||
})
|
||||
40
pocketbase/pb_hooks/resetCounter.pb.js
Normal file
40
pocketbase/pb_hooks/resetCounter.pb.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/// <reference path="../pb_data/types.d.ts" />
|
||||
|
||||
/**
|
||||
* POST endpoint to reset the user's counter to 0,
|
||||
* additionally sends a notification to the user.
|
||||
* Requires authentication.
|
||||
*/
|
||||
routerAdd('POST', '/counter/reset', (e) => {
|
||||
try {
|
||||
const authRecord = e.auth
|
||||
|
||||
// find the user's counter record
|
||||
const counterRecord = $app.findFirstRecordByData('counters', 'userId', authRecord.id)
|
||||
|
||||
if (counterRecord) {
|
||||
// reset the counter to 0 and save
|
||||
counterRecord.set('count', 0)
|
||||
$app.save(counterRecord)
|
||||
}
|
||||
|
||||
// get the user's language and load the locale
|
||||
const userRecord = $app.findFirstRecordByData('users', 'id', authRecord.id)
|
||||
const language = userRecord?.getString('language') ?? 'en'
|
||||
const locale = require(`${__hooks}/locales/${language}.json`)
|
||||
const t = locale.resetCounter
|
||||
|
||||
// add notification
|
||||
const collection = $app.findCollectionByNameOrId('notifications')
|
||||
const notificationRecord = new Record(collection)
|
||||
notificationRecord.set('userId', authRecord.id)
|
||||
notificationRecord.set('title', t.title)
|
||||
notificationRecord.set('body', t.body)
|
||||
$app.save(notificationRecord)
|
||||
|
||||
return e.noContent(204)
|
||||
} catch (error) {
|
||||
console.error('Error', error)
|
||||
return e.json(500, { message: error.message })
|
||||
}
|
||||
}, $apis.requireAuth())
|
||||
55
pocketbase/pb_hooks/sendFcmPush.pb.js
Normal file
55
pocketbase/pb_hooks/sendFcmPush.pb.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/// <reference path="../pb_data/types.d.ts" />
|
||||
|
||||
onRecordAfterCreateSuccess((e) => {
|
||||
const record = e.record
|
||||
const userId = record.getString('userId')
|
||||
|
||||
if (!userId) return e.next()
|
||||
|
||||
const tokenRecords = $app.findRecordsByFilter(
|
||||
'fcm_tokens',
|
||||
`userId = "${userId}"`,
|
||||
'-created',
|
||||
500,
|
||||
0
|
||||
)
|
||||
|
||||
if (!tokenRecords || tokenRecords.length === 0) return e.next()
|
||||
|
||||
const tokens = tokenRecords
|
||||
.map(r => r.getString('token'))
|
||||
.filter(t => t.length > 0)
|
||||
|
||||
if (tokens.length === 0) return e.next()
|
||||
|
||||
const sidecarUrl = $os.getenv('SIDECAR_URL') || 'http://localhost:8091'
|
||||
const sidecarSecret = $os.getenv('SIDECAR_SECRET') || ''
|
||||
|
||||
try {
|
||||
const res = $http.send({
|
||||
url: sidecarUrl + '/notify',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'x-sidecar-secret': sidecarSecret
|
||||
},
|
||||
body: JSON.stringify({
|
||||
tokens: tokens,
|
||||
title: record.getString('title'),
|
||||
body: record.getString('body')
|
||||
}),
|
||||
timeout: 10
|
||||
})
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
e.app.logger().error('FCM relay failed',
|
||||
'status', res.statusCode,
|
||||
'response', JSON.stringify(res.json)
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
e.app.logger().error('FCM relay error', 'error', err)
|
||||
}
|
||||
|
||||
return e.next()
|
||||
}, 'notifications')
|
||||
14
pocketbase/pb_hooks/templates/de/authAlert.html
Normal file
14
pocketbase/pb_hooks/templates/de/authAlert.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hallo,</p>
|
||||
<p>Wir haben eine Anmeldung bei deinem {{.appName}}-Konto von einem neuen Standort festgestellt:</p>
|
||||
<p><em>{{.info}}</em></p>
|
||||
<p><strong>Wenn du das nicht warst, solltest du sofort dein {{.appName}}-Passwort ändern, um den Zugriff von allen anderen Standorten zu widerrufen.</strong></p>
|
||||
<p>Wenn du das warst, kannst du diese E-Mail ignorieren.</p>
|
||||
<p>
|
||||
Viele Grüße,<br/>
|
||||
Das {{.appName}}-Team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
15
pocketbase/pb_hooks/templates/de/emailChange.html
Normal file
15
pocketbase/pb_hooks/templates/de/emailChange.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hallo,</p>
|
||||
<p>Klicke auf den Button unten, um deine neue E-Mail-Adresse zu bestätigen.</p>
|
||||
<p>
|
||||
<a class="btn" href="{{.appUrl}}/_/#/auth/confirm-email-change/{{.token}}" target="_blank" rel="noopener">Neue E-Mail-Adresse bestätigen</a>
|
||||
</p>
|
||||
<p><i>Wenn du keine Änderung deiner E-Mail-Adresse beantragt hast, kannst du diese E-Mail ignorieren.</i></p>
|
||||
<p>
|
||||
Viele Grüße,<br/>
|
||||
Das {{.appName}}-Team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
12
pocketbase/pb_hooks/templates/de/otp.html
Normal file
12
pocketbase/pb_hooks/templates/de/otp.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hallo,</p>
|
||||
<p>Dein Einmalpasswort lautet: <strong>{{.password}}</strong></p>
|
||||
<p><i>Wenn du kein Einmalpasswort angefordert hast, kannst du diese E-Mail ignorieren.</i></p>
|
||||
<p>
|
||||
Viele Grüße,<br/>
|
||||
Das {{.appName}}-Team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
15
pocketbase/pb_hooks/templates/de/passwortReset.html
Normal file
15
pocketbase/pb_hooks/templates/de/passwortReset.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hallo,</p>
|
||||
<p>Klicke auf den Button unten, um dein Passwort zurückzusetzen.</p>
|
||||
<p>
|
||||
<a class="btn" href="{{.appUrl}}/_/#/auth/confirm-password-reset/{{.token}}" target="_blank" rel="noopener">Passwort zurücksetzen</a>
|
||||
</p>
|
||||
<p><i>Wenn du keine Passwortzurücksetzung beantragt hast, kannst du diese E-Mail ignorieren.</i></p>
|
||||
<p>
|
||||
Viele Grüße,<br/>
|
||||
Das {{.appName}}-Team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
15
pocketbase/pb_hooks/templates/de/verification.html
Normal file
15
pocketbase/pb_hooks/templates/de/verification.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hallo,</p>
|
||||
<p>Willkommen bei {{.appName}}.</p>
|
||||
<p>Klicke auf den Button unten, um deine E-Mail-Adresse zu bestätigen.</p>
|
||||
<p>
|
||||
<a class="btn" href="{{.appUrl}}/_/#/auth/confirm-verification/{{.token}}" target="_blank" rel="noopener">E-Mail-Adresse bestätigen</a>
|
||||
</p>
|
||||
<p>
|
||||
Viele Grüße,<br/>
|
||||
Das {{.appName}}-Team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
14
pocketbase/pb_hooks/templates/en/authAlert.html
Normal file
14
pocketbase/pb_hooks/templates/en/authAlert.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>We noticed a login to your {{.appName}} account from a new location:</p>
|
||||
<p><em>{{.info}}</em></p>
|
||||
<p><strong>If this wasn't you, you should immediately change your {{.appName}} account password to revoke access from all other locations.</strong></p>
|
||||
<p>If this was you, you may disregard this email.</p>
|
||||
<p>
|
||||
Thanks,<br/>
|
||||
{{.appName}} team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
15
pocketbase/pb_hooks/templates/en/emailChange.html
Normal file
15
pocketbase/pb_hooks/templates/en/emailChange.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>Click on the button below to confirm your new email address.</p>
|
||||
<p>
|
||||
<a class="btn" href="{{.appUrl}}/_/#/auth/confirm-email-change/{{.token}}" target="_blank" rel="noopener">Confirm new email</a>
|
||||
</p>
|
||||
<p><i>If you didn't ask to change your email address, you can ignore this email.</i></p>
|
||||
<p>
|
||||
Thanks,<br/>
|
||||
{{.appName}} team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
12
pocketbase/pb_hooks/templates/en/otp.html
Normal file
12
pocketbase/pb_hooks/templates/en/otp.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>Your one-time password is: <strong>{{.password}}</strong></p>
|
||||
<p><i>If you didn't ask for the one-time password, you can ignore this email.</i></p>
|
||||
<p>
|
||||
Thanks,<br/>
|
||||
{{.appName}} team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
15
pocketbase/pb_hooks/templates/en/passwortReset.html
Normal file
15
pocketbase/pb_hooks/templates/en/passwortReset.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>Click on the button below to reset your password.</p>
|
||||
<p>
|
||||
<a class="btn" href="{{.appUrl}}/_/#/auth/confirm-password-reset/{{.token}}" target="_blank" rel="noopener">Reset password</a>
|
||||
</p>
|
||||
<p><i>If you didn't ask to reset your password, you can ignore this email.</i></p>
|
||||
<p>
|
||||
Thanks,<br/>
|
||||
{{.appName}} team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
15
pocketbase/pb_hooks/templates/en/verification.html
Normal file
15
pocketbase/pb_hooks/templates/en/verification.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
<p>Thank you for joining us at {{.appName}}.</p>
|
||||
<p>Click on the button below to verify your email address.</p>
|
||||
<p>
|
||||
<a class="btn" href="{{.appUrl}}/_/#/auth/confirm-verification/{{.token}}" target="_blank" rel="noopener">Verify</a>
|
||||
</p>
|
||||
<p>
|
||||
Thanks,<br/>
|
||||
{{.appName}} team
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
29
pocketbase/pb_hooks/utils/renderMailTemplate.js
Normal file
29
pocketbase/pb_hooks/utils/renderMailTemplate.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const renderMailTemplate = (e, type) => {
|
||||
try {
|
||||
const language = e.record?.getString('language') ?? 'en'
|
||||
const locale = require(`${__hooks}/locales/${language}.json`)
|
||||
|
||||
const subject = $template.loadString(
|
||||
locale.mailSubject[type]
|
||||
).render({
|
||||
...e.meta,
|
||||
...e.app.settings().meta
|
||||
})
|
||||
|
||||
const html = $template.loadFiles(
|
||||
`${__hooks}/templates/${language}/${type}.html`
|
||||
).render({
|
||||
...e.meta,
|
||||
...e.app.settings().meta
|
||||
})
|
||||
|
||||
e.message.subject = subject
|
||||
e.message.html = html
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
e.next()
|
||||
}
|
||||
|
||||
module.exports = { renderMailTemplate }
|
||||
Reference in New Issue
Block a user