sumba 1.0.17 → 1.0.19

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.
Files changed (58) hide show
  1. package/bajo/hook/dobo@before-record-get.js +1 -1
  2. package/bajo/hook/waibu-mpa.sumba@after-build-locals.js +6 -6
  3. package/bajo/hook/waibu-mpa@pre-parsing.js +6 -6
  4. package/bajo/hook/waibu@after-app-boot.js +5 -5
  5. package/bajo/intl/en-US.json +89 -0
  6. package/bajo/intl/id.json +90 -0
  7. package/bajo/method/get-user-from-username-password.js +3 -3
  8. package/bajo/method/verify/api-key.js +2 -2
  9. package/bajo/method/verify/jwt.js +2 -2
  10. package/bajo/method/verify/session.js +1 -1
  11. package/bajoAdmin/coll/user.json +2 -2
  12. package/lib/check-site-id.js +2 -2
  13. package/lib/check-user-id.js +4 -4
  14. package/package.json +1 -1
  15. package/waibuDb/schema/user.json +4 -4
  16. package/waibuMpa/partial/api-key-modal.html +4 -4
  17. package/waibuMpa/partial/help/contact-form/success.html +4 -4
  18. package/waibuMpa/partial/help/trouble-tickets/list.html +0 -1
  19. package/waibuMpa/partial/list-item/member-links.html +6 -6
  20. package/waibuMpa/partial/list-item/your-profile.html +1 -1
  21. package/waibuMpa/partial/my-stuff/change-password.html +12 -0
  22. package/waibuMpa/partial/my-stuff/profile/edit.html +50 -0
  23. package/waibuMpa/partial/my-stuff/profile/view.html +34 -0
  24. package/waibuMpa/partial/my-stuff/reset-api-key.html +12 -0
  25. package/waibuMpa/partial/signout.html +2 -2
  26. package/waibuMpa/partial/user/activation.html +10 -0
  27. package/waibuMpa/partial/user/forgot-password.html +10 -0
  28. package/waibuMpa/partial/user/signup/form.html +16 -0
  29. package/waibuMpa/partial/user/signup/success.html +8 -0
  30. package/waibuMpa/route/my-stuff/change-password.js +3 -3
  31. package/waibuMpa/route/my-stuff/profile/edit.js +1 -1
  32. package/waibuMpa/route/my-stuff/reset-api-key.js +3 -3
  33. package/waibuMpa/route/signin.js +1 -1
  34. package/waibuMpa/route/signout.js +2 -2
  35. package/waibuMpa/route/user/activation.js +2 -2
  36. package/waibuMpa/route/user/signup.js +1 -1
  37. package/waibuMpa/template/help/contact-form/form.html +1 -2
  38. package/waibuMpa/template/help/contact-form/success.html +1 -2
  39. package/waibuMpa/template/help/trouble-tickets/list.html +1 -2
  40. package/waibuMpa/template/info/about-us.id.md +1 -2
  41. package/waibuMpa/template/info/about-us.md +1 -1
  42. package/waibuMpa/template/info/cookie-policy.md +1 -1
  43. package/waibuMpa/template/info/privacy.md +1 -1
  44. package/waibuMpa/template/info/terms-conditions.md +1 -1
  45. package/waibuMpa/template/my-stuff/change-password.html +1 -13
  46. package/waibuMpa/template/my-stuff/profile/edit.html +1 -51
  47. package/waibuMpa/template/my-stuff/profile/view.html +1 -35
  48. package/waibuMpa/template/my-stuff/reset-api-key.html +1 -13
  49. package/waibuMpa/template/signin.html +1 -1
  50. package/waibuMpa/template/signout.html +1 -1
  51. package/waibuMpa/template/user/activation.html +1 -11
  52. package/waibuMpa/template/user/forgot-password.html +1 -11
  53. package/waibuMpa/template/user/signup/form.html +1 -17
  54. package/waibuMpa/template/user/signup/success.html +1 -9
  55. package/waibuRestApi/route/my-stuff/change-password/update.js +1 -1
  56. package/waibuRestApi/route/user/access-token/@type/create.js +1 -1
  57. package/bajoI18N/resource/en-US.json +0 -11
  58. package/bajoI18N/resource/id.json +0 -78
@@ -11,7 +11,7 @@ export async function checker (model, id, options = {}) {
11
11
  const filter = { query: { id }, limit: 1 }
12
12
  filter.query[i] = rec
13
13
  const rows = await recordFind(model, filter)
14
- if (rows.length === 0) throw this.error('Record \'%s@%s\' not found!', id, model, { statusCode: 404 })
14
+ if (rows.length === 0) throw this.error('recordNotFound%s%s', id, model, { statusCode: 404 })
15
15
  }
16
16
  }
17
17
  }
@@ -2,13 +2,13 @@ async function afterBuildLocals (locals, req) {
2
2
  const { routePath } = this.app.waibu
3
3
  const items = []
4
4
  if (req.user) {
5
- items.push({ icon: 'person', tooltip: 'Your Profile', href: routePath('sumba:/my-stuff/profile') })
6
- items.push({ icon: 'key', tooltip: 'Change Password', href: routePath('sumba:/my-stuff/change-password') })
7
- items.push({ component: 'navItemSignout', tooltip: 'Signout', bottom: true })
5
+ items.push({ icon: 'person', tooltip: 'yourProfile', href: routePath('sumba:/my-stuff/profile') })
6
+ items.push({ icon: 'key', tooltip: 'changePassword', href: routePath('sumba:/my-stuff/change-password') })
7
+ items.push({ component: 'navItemSignout', tooltip: 'signout', bottom: true })
8
8
  } else {
9
- items.push({ icon: 'signin', tooltip: 'Signin', href: routePath('sumba:/signin') })
10
- items.push({ icon: 'key', tooltip: 'Forgot Password', href: routePath('sumba:/user/forgot-password') })
11
- items.push({ icon: 'personAdd', tooltip: 'New User Signup', href: routePath('sumba:/user/signup') })
9
+ items.push({ icon: 'signin', tooltip: 'signin', href: routePath('sumba:/signin') })
10
+ items.push({ icon: 'key', tooltip: 'forgotPassword', href: routePath('sumba:/user/forgot-password') })
11
+ items.push({ icon: 'personAdd', tooltip: 'newUserSignup', href: routePath('sumba:/user/signup') })
12
12
  }
13
13
  for (const item of items) {
14
14
  if (locals._meta.url.startsWith(item.href)) item.active = true
@@ -13,17 +13,17 @@ const preParsing = {
13
13
  req.menu = req.menu ?? {}
14
14
  if (req.user) {
15
15
  req.menu.user = [
16
- { value: routePath('sumba:/change-password', req), text: req.i18n.t('Change Password') },
17
- { value: routePath('sumba:/profile', req), text: req.i18n.t('Your Profile') },
16
+ { value: routePath('sumba:/change-password', req), text: req.t('Change Password') },
17
+ { value: routePath('sumba:/profile', req), text: req.t('yourProfile') },
18
18
  '-',
19
- { value: routePath('sumba:/signout', req), text: req.i18n.t('Signout') }
19
+ { value: routePath('sumba:/signout', req), text: req.t('signout') }
20
20
  ]
21
21
  } else {
22
22
  req.menu.user = [
23
- { value: routePath('sumba:/signin', req), text: req.i18n.t('Signin') },
23
+ { value: routePath('sumba:/signin', req), text: req.t('signin') },
24
24
  '-',
25
- { value: routePath('sumba:/signup', req), text: req.i18n.t('Signup') },
26
- { value: routePath('sumba:/forgot-password', req), text: req.i18n.t('Forgot Password') }
25
+ { value: routePath('sumba:/signup', req), text: req.t('signup') },
26
+ { value: routePath('sumba:/forgot-password', req), text: req.t('forgotPassword') }
27
27
  ]
28
28
  }
29
29
  }
@@ -1,13 +1,13 @@
1
1
  import collectRoutes from '../../lib/collect-routes.js'
2
2
 
3
3
  async function afterAppBoot () {
4
- this.log.trace('Collecting route guards:')
4
+ this.log.trace('collectingRouteGuards')
5
5
  await collectRoutes.call(this, 'secure')
6
6
  await collectRoutes.call(this, 'anonymous')
7
- this.log.trace('- Secure routes: %d', this.secureRoutes.length)
8
- this.log.trace('- Secure, inverted routes: %d', this.secureInvRoutes.length)
9
- this.log.trace('- Anonymous routes: %d', this.anonymousRoutes.length)
10
- this.log.trace('- Anonymous, inverted routes: %d', this.anonymousInvRoutes.length)
7
+ this.log.trace('secureRoutes%d', this.secureRoutes.length)
8
+ this.log.trace('secureInvRoutes%d', this.secureInvRoutes.length)
9
+ this.log.trace('anonRoutes%d', this.anonymousRoutes.length)
10
+ this.log.trace('anonInvRoutes%d', this.anonymousInvRoutes.length)
11
11
  }
12
12
 
13
13
  export default afterAppBoot
@@ -0,0 +1,89 @@
1
+ {
2
+ "invalidKey": "Invalid api key provided",
3
+ "userInactive": "User is inactive or temporarily disabled",
4
+ "invalidToken": "Invalid token or token is expired",
5
+ "unknownUsername": "Unknown username",
6
+ "invalidPassword": "Invalid password",
7
+ "unknownSite": "Unknown site or site is not configured yet",
8
+ "siteInactiveInfo": "This site is currently inactive or disabled. Please contact your admin, thanks!",
9
+ "noAuthMethod": "No authentication method found. Please contact your admin immediately!",
10
+ "invalidAuthMethod%s": "Invalid authentication method '%s'",
11
+ "accessDenied": "Access denied. Can't authenticate you through all available methods",
12
+ "invalidTokenType": "Invalid token type",
13
+ "invalidCurrentPassword": "Invalid current password",
14
+ "themeGloballyDisabled": "Theme support is globally disabled!",
15
+ "themeNotInstalled%s": "Theme '%s' is not installed",
16
+ "profile": "Profile",
17
+ "yourProfile": "Your Profile",
18
+ "editYourProfile": "Edit Your Profile",
19
+ "account": "Account",
20
+ "address": "Address",
21
+ "phoneEmail": "Phone/Email",
22
+ "changePassword": "Change Password",
23
+ "signout": "Signout",
24
+ "signin": "Signin",
25
+ "yourStuff": "Your Stuff",
26
+ "forgotPassword": "Forgot Password",
27
+ "userActivation": "User Activation",
28
+ "signup": "Signup",
29
+ "newUserSignup": "New User Signup",
30
+ "updateProfile": "Update Profile",
31
+ "backToProfile": "Back To Profile",
32
+ "displayApiKey": "Display API Key",
33
+ "apiKey": "API Key",
34
+ "aboutUs": "About Us",
35
+ "invalidActivationKey": "Invalid activation key",
36
+ "signoutNow": "Yes, sign me out now",
37
+ "signoutWarning": "You\\'re about to sign out. This means your session will be cleared and you\\'ll be asked for your credential again in case you want to access any protected pages and resources.<br /><br />Are your sure?",
38
+ "clearInvalidKey": "Clear Invalid Fields",
39
+ "linkPasswordWillbeSent": "Link to reset password will be sent to your email",
40
+ "signinSuccessfully": "You've successfully signed in",
41
+ "signoutSuccessfully": "You've successfully signed out",
42
+ "profileUpdated": "Your profile has been successfully updated",
43
+ "passwordChangedReSignin": "You've successfully changed your password. Now please re-signin with your new password",
44
+ "agreeToTerm%s%s": "I agree to the <a href=\"%s\">%s</a>",
45
+ "userActivated": "User account successfully activated",
46
+ "userCreated": "User account successfully created",
47
+ "resetApiKey": "Reset API Key",
48
+ "resetApiKeySuccessfull": "You've successfully reset your API key",
49
+ "personInCharge": "Person In Charge",
50
+ "contactForm": "Contact Form",
51
+ "terms": "Terms",
52
+ "cookie": "Cookie Policy",
53
+ "cookiePolicy": "Cookie Policy",
54
+ "privacy": "Privacy Statement",
55
+ "termsConditions": "Terms and Conditions",
56
+ "privacyStatement": "Privacy Statement",
57
+ "legalInfo": "Legal Info",
58
+ "help": "Help",
59
+ "troubleTickets": "Trouble Tickets",
60
+ "guest": "Guest",
61
+ "formSubmitted": "Form submitted successfully",
62
+ "formSubmittedInfo": "Please allow us to read your submission thoroughly and we'll get back to you rightaway",
63
+ "thankYou": "Thank you!",
64
+ "warningMemberOnly%s": "Please authenticate yourself first, because the <a href=\"%s\">page<a> your're trying to access is a member only page",
65
+ "collectingRouteGuards": "Collecting route guards:",
66
+ "secureRoutes%d": "- Secure routes: %d",
67
+ "secureInvRoutes%d": "- Secure, inverted routes: %d",
68
+ "anonRoutes%d": "- Anonymous routes: %d",
69
+ "anonInvRoutes%d": "- Anonymous, inverted routes: %d",
70
+ "field": {
71
+ "currentPassword": "Current Password",
72
+ "newPassword": "New Password",
73
+ "verifyNewPassword": "Verify New Password",
74
+ "usernameEmail": "Username/Email",
75
+ "apiKey": "API Key",
76
+ "hostname": "Hostname",
77
+ "iconset": "Iconset",
78
+ "subject": "Subject",
79
+ "message": "Message"
80
+ },
81
+ "validation": {
82
+ "password.minOfUppercase": "Contains at leaset {{min}} uppercase characters",
83
+ "password.minOfSpecialCharacters": "Contains at least {{min}} special characters",
84
+ "password.minOfLowercase": "Contains at least {{min}} special characters",
85
+ "password.minOfNumeric": "Contains at least {{min}} numerical characters",
86
+ "password.noWhiteSpaces": "No space allowed",
87
+ "password.onlyLatinCharacters": "Only latin characters allowed"
88
+ }
89
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "invalidKey": "Kunci API yang diberikan tidak valud",
3
+ "userInactive": "Pengguna sedang tidak aktif atau sedang ditangguhkan secara temporer",
4
+ "invalidToken": "Token tidak valid atau token telah kadaluarsa",
5
+ "unknownUsername": "Nama pengguna tidak dikenal",
6
+ "invalidPassword": "Kata kunci tidak valid",
7
+ "unknownSite": "Situs tidak dikenal atau situs ini belum dikonfigurasikan dengan benar",
8
+ "siteInactiveInfo": "Situs sedang tidak aktif atau sedang ditangguhkan. Silahkan hubungi admin Anda segera!",
9
+ "noAuthMethod": "Tidak ditemukan metode otentikasi satupun. Silahkan hubungi admin Anda segera!",
10
+ "invalidAuthMethod%s": "Metode otentikasi '%s' tidak valid",
11
+ "accessDenied": "Akses ditolak. Tidak bisa mengotentikasi Anda dengan seluruh metode yang tersedia",
12
+ "invalidTokenType": "Tipe token tidak valid",
13
+ "invalidCurrentPassword": "Kata sandi saat ini tidak valid",
14
+ "themeGloballyDisabled": "Dukungan tema secara global tidak aktif!",
15
+ "themeNotInstalled%s": "Tema '%s' tidak terinstall",
16
+ "profile": "Profil",
17
+ "yourProfile": "Profil Anda",
18
+ "editYourProfile": "Edit Profil Anda",
19
+ "account": "Akun",
20
+ "address": "Alamat",
21
+ "phoneEmail": "Telpon/Surel",
22
+ "changePassword": "Ganti Kata Sandi",
23
+ "signout": "Keluar",
24
+ "signin": "Masuk",
25
+ "yourStuff": "Perkakas Anda",
26
+ "forgotPassword": "Lupa Kata Sandi",
27
+ "userActivation": "Aktivasi Pengguna",
28
+ "signup": "Pendaftaran",
29
+ "newUserSignup": "Pendaftaran Pengguna Baru",
30
+ "updateProfile": "Perbarui Profil",
31
+ "backToProfile": "Kembali ke Profil",
32
+ "displayApiKey": "Tampilkan Kunci API",
33
+ "apiKey": "Kunci API",
34
+ "aboutUs": "Tentang Kami",
35
+ "invalidActivationKey": "Kunci otentikasi tidak valid",
36
+ "signoutNow": "Ya, keluarkan saya sekarang juga",
37
+ "signoutWarning": "Anda akan keluar. Ini berarti sesi Anda akan dihapus dan Anda akan ditanyakan kembali kredensial Anda jika Anda akan mengakses halaman-halaman yang diproteksi.<br /><br />Anda yakin?",
38
+ "clearInvalidKey": "Bersihkan Kolom Tidak Valid",
39
+ "linkPasswordWillbeSent": "Tautan untuk mengubah kata sandi akan dikirim ke surel Anda",
40
+ "signinSuccessfully": "Anda sukses melakukan login",
41
+ "signoutSuccessfully": "Anda sukses melakukan logout",
42
+ "profileUpdated": "Profil Anda sukses diperbaru",
43
+ "passwordChangedReSignin": "Anda sukses melakukan perbaruan kata kunci. Sekarang silahkan melakukan login ulang dengan kata kunci baru Anda",
44
+ "agreeToTerm%s%s": "Saya setuju dengan semua <a href=\"%s\">%s</a> yang berlaku",
45
+ "userActivated": "Akun pengguna sukses diaktivasi",
46
+ "userCreated": "Akun pengguna sukses dibuat",
47
+ "resetApiKey": "Reset Kunci API",
48
+ "resetApiKeySuccessfull": "Anda sukses mereset kunci API anda",
49
+ "personInCharge": "Penanggung Jawab",
50
+ "contactForm": "Form Kontak",
51
+ "cookie": "Cookie",
52
+ "cookiePolicy": "Kebijakan Cookie",
53
+ "privacy": "Privasi",
54
+ "privacyStatement": "Pernyataan Privasi",
55
+ "terms": "Terms",
56
+ "termsConditions": "Term dan Kondisi",
57
+ "legalInfo": "Info Legal",
58
+ "help": "Bantuan",
59
+ "troubleTickets": "Tiket Masalah",
60
+ "guest": "Tamu",
61
+ "formSubmitted": "Formulir sukses dikirim",
62
+ "formSubmittedInfo": "Kami akan mereview sebentar kiriman Anda dan akan menghubungi Anda kembali secepatnya",
63
+ "thankYou": "Thank you!",
64
+ "warningMemberOnly%s": "Silahkan melalukan otentikasi terlebih dahulu karena <a href=\"%s\">halaman<a> yang akan Anda akses adalah salah satu halaman khusus anggota saja",
65
+ "collectingRouteGuards": "Mengoleksi pertahanan jalur:",
66
+ "secureRoutes%d": "- Jalur aman: %d",
67
+ "secureInvRoutes%d": "- Jalur aman, terbalik: %d",
68
+ "anonRoutes%d": "- Jalur anonim: %d",
69
+ "anonInvRoutes%d": "- Jalur anonim, terbalik: %d",
70
+ "field": {
71
+ "currentPassword": "Kata Sandi Saat Ini",
72
+ "newPassword": "Kata Sandi Baru",
73
+ "verifyPassword": "Verifikasi Kata Sandi",
74
+ "verifyNewPassword": "Verifikasi Sandi Baru",
75
+ "usernameEmail": "Nama Pengguna/Surel",
76
+ "apiKey": "Kunci API",
77
+ "hostname": "Nama Host",
78
+ "iconset": "Iconset",
79
+ "subject": "Judul",
80
+ "message": "Pesan"
81
+ },
82
+ "validation": {
83
+ "password.minOfUppercase": "Mengandung setidaknya {{min}} huruf besar",
84
+ "password.minOfSpecialCharacters": "Mengandung setidaknya {{min}} karakter spesial",
85
+ "password.minOfLowercase": "Mengandung setidaknya {{min}} huruf kecil",
86
+ "password.minOfNumeric": "Mengandung setidaknya {{min}} numerik/angka",
87
+ "password.noWhiteSpaces": "Tidak boleh ada spasi",
88
+ "password.onlyLatinCharacters": "Harus berupa karakter latin saja"
89
+ }
90
+ }
@@ -8,11 +8,11 @@ async function getUserByUsernamePassword (username = '', password = '', req) {
8
8
 
9
9
  const query = { username }
10
10
  const rows = await recordFind(model, { query }, { req, forceNoHidden: true, noHook: true })
11
- if (rows.length === 0) throw this.error('Validation Error', { details: [{ field: 'username', error: 'Unknown username' }], statusCode: 401 })
11
+ if (rows.length === 0) throw this.error('validationError', { details: [{ field: 'username', error: 'Unknown username' }], statusCode: 401 })
12
12
  const rec = rows[0]
13
- if (rec.status !== 'ACTIVE') throw this.error('Validation Error', { details: ['User is inactive or temporarily disabled'], statusCode: 401 })
13
+ if (rec.status !== 'ACTIVE') throw this.error('validationError', { details: ['User is inactive or temporarily disabled'], statusCode: 401 })
14
14
  const verified = await bcrypt.compare(password, rec.password)
15
- if (!verified) throw this.error('Validation Error', { details: [{ field: 'password', error: 'Invalid password' }], statusCode: 401 })
15
+ if (!verified) throw this.error('validationError', { details: [{ field: 'password', error: 'invalidPassword' }], statusCode: 401 })
16
16
  return rec
17
17
  }
18
18
 
@@ -31,8 +31,8 @@ async function verifyApiKey (req, reply, source) {
31
31
  token = await hash(token)
32
32
  const query = { token }
33
33
  const rows = await recordFind('SumbaUser', { query }, { req, noHook: true })
34
- if (rows.length === 0) throw this.error('Invalid api key provided', { statusCode: 401 })
35
- if (rows[0].status !== 'ACTIVE') throw this.error('User is inactive or temporarily disabled', { details: [{ field: 'status', error: 'inactive' }], statusCode: 401 })
34
+ if (rows.length === 0) throw this.error('invalidKey', { statusCode: 401 })
35
+ if (rows[0].status !== 'ACTIVE') throw this.error('userInactive', { details: [{ field: 'status', error: 'inactive' }], statusCode: 401 })
36
36
  req.user = await getUser(rows[0])
37
37
  return true
38
38
  }
@@ -19,8 +19,8 @@ async function verifyJwt (req, reply, source) {
19
19
  const id = decoded.payload.uid
20
20
  try {
21
21
  const rec = await recordGet('SumbaUser', id, { req, noHook: true })
22
- if (!rec) throw this.error('Invalid token or token is expired', { statusCode: 401 })
23
- if (rec.status !== 'ACTIVE') throw this.error('User is inactive or temporarily disabled', { details: [{ field: 'status', error: 'inactive' }], statusCode: 401 })
22
+ if (!rec) throw this.error('invalidToken', { statusCode: 401 })
23
+ if (rec.status !== 'ACTIVE') throw this.error('userInactive', { details: [{ field: 'status', error: 'inactive' }], statusCode: 401 })
24
24
  req.user = await getUser(rec)
25
25
  return true
26
26
  } catch (err) {
@@ -9,7 +9,7 @@ async function verifySession (req, reply, source) {
9
9
  }
10
10
  const redir = routePath(this.config.redirect.signin, req)
11
11
  req.session.ref = req.url
12
- throw this.error('redirect', { redirect: redir })
12
+ throw this.error('_redirect', { redirect: redir })
13
13
  }
14
14
 
15
15
  export default verifySession
@@ -17,7 +17,7 @@
17
17
  "status;small:12,medium:4"
18
18
  ]
19
19
  }, {
20
- "title": "Account",
20
+ "title": "account",
21
21
  "fields": [
22
22
  "username;small:6,medium:6",
23
23
  "email;small:6,medium:6",
@@ -62,7 +62,7 @@
62
62
  "status;small:12,medium:4"
63
63
  ]
64
64
  }, {
65
- "title": "Account",
65
+ "title": "account",
66
66
  "fields": [
67
67
  "username;small:6,medium:6",
68
68
  "email;small:6,medium:6",
@@ -44,9 +44,9 @@ async function checkSiteId (req, reply) {
44
44
  }
45
45
  const filter = { query }
46
46
  const rows = await recordFind('SumbaSite', filter, { noHook: true })
47
- if (rows.length === 0) throw this.error('Unknown site or site is not configured yet')
47
+ if (rows.length === 0) throw this.error('unknownSite')
48
48
  const row = omit(rows[0], omitted)
49
- if (row.status !== 'ACTIVE') throw this.error('This site is currently inactive or disabled. Please contact your admin, thanks!')
49
+ if (row.status !== 'ACTIVE') throw this.error('siteInactiveInfo')
50
50
  req.site = row
51
51
  await mergeSetting.call(this, req)
52
52
  }
@@ -34,7 +34,7 @@ async function anonymous (req) {
34
34
  if (match) {
35
35
  const redir = routePath(this.config.redirect.signout, req)
36
36
  req.session.ref = req.url
37
- throw this.error('redirect', { redirect: redir })
37
+ throw this.error('_redirect', { redirect: redir })
38
38
  }
39
39
  req.user = omit(await getUser(req.session.user.id), ['password', 'token'])
40
40
  }
@@ -73,18 +73,18 @@ async function checkUserId (req, reply, source) {
73
73
  return
74
74
  }
75
75
  const authMethods = this.config.auth[match.source].methods ?? []
76
- if (isEmpty(authMethods)) throw this.error('No authentication method found. Please contact your admin immediately!', { statusCode: 500 })
76
+ if (isEmpty(authMethods)) throw this.error('noAuthMethod', { statusCode: 500 })
77
77
  let success
78
78
  for (const m of authMethods) {
79
79
  const handler = this[camelCase(`verify ${m}`)]
80
- if (!handler) throw this.error('Invalid authentication method \'%s\'', m, { statusCode: 500 })
80
+ if (!handler) throw this.error('invalidAuthMethod%s', m, { statusCode: 500 })
81
81
  const check = await handler(req, reply, source, ctx)
82
82
  if (check) {
83
83
  success = check
84
84
  break
85
85
  }
86
86
  }
87
- if (!success) throw this.error('Access denied. Can\'t authenticate you through all available methods', { statusCode: 401 })
87
+ if (!success) throw this.error('accessDenied', { statusCode: 401 })
88
88
  await mergeSetting.call(this, req)
89
89
  return success
90
90
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sumba",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "Bajo Framework's Biz Suite",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "common": {
3
3
  "layout": [
4
- { "name": "Meta", "fields": ["id", "createdAt", "updatedAt"] },
5
- { "name": "Account", "fields": ["username", "email", "status:4-md 6-sm", "siteId:4-md 6-sm", "firstName", "lastName"] },
6
- { "name": "Address", "fields": ["address1:12", "address2:12", "city:6-md 8-sm", "zipCode:2-md 4-sm", "provinceState:4-md", { "name": "country", "col": "6-md", "component": "form-select-country" }, "phone:6-md", "website:12"] },
7
- { "name": "Social Media", "fields": ["twitter:3-md 6-sm", "instagram:3-md 6-sm", "facebook:3-md 6-sm", "linkedIn:3-md 6-sm"] }
4
+ { "name": "meta", "fields": ["id", "createdAt", "updatedAt"] },
5
+ { "name": "account", "fields": ["username", "email", "status:4-md 6-sm", "siteId:4-md 6-sm", "firstName", "lastName"] },
6
+ { "name": "address", "fields": ["address1:12", "address2:12", "city:6-md 8-sm", "zipCode:2-md 4-sm", "provinceState:4-md", { "name": "country", "col": "6-md", "component": "form-select-country" }, "phone:6-md", "website:12"] },
7
+ { "name": "socialMedia", "fields": ["twitter:3-md 6-sm", "instagram:3-md 6-sm", "facebook:3-md 6-sm", "linkedIn:3-md 6-sm"] }
8
8
  ],
9
9
  "stat": {
10
10
  "aggregate": [
@@ -1,11 +1,11 @@
1
- <c:modal id="api-key-modal" t:title="API Key">
1
+ <c:modal id="api-key-modal" t:title="apiKey">
2
2
  <c:modal-body>
3
3
  <pre><code id="api-key"><%= form.token %></code></pre>
4
4
  <c:div flex="justify-content:between align-items:center" margin="top-3">
5
- <c:a icon="arrowsRepeat" href="sumba:/my-stuff/reset-api-key" t:content="Reset" />
5
+ <c:a icon="arrowsRepeat" href="sumba:/my-stuff/reset-api-key" t:content="reset" />
6
6
  <div>
7
- <c:btn color="primary" x-data @click="await wbs.copyToClipboard('#api-key', true)" t:content="Copy to Clipboard" />
8
- <c:btn margin="start-1" color="secondary" dismiss t:content="Close" />
7
+ <c:btn color="primary" x-data @click="await wbs.copyToClipboard('#api-key', true)" t:content="copyClipboard" />
8
+ <c:btn margin="start-1" color="secondary" dismiss t:content="close" />
9
9
  </div>
10
10
  </c:div>
11
11
  </c:modal-body>
@@ -1,8 +1,8 @@
1
- <c:p t:content="Form submitted successfully!" />
2
- <c:p t:content="Please allow us to read your submission thoroughly and we'll get back to you as soon as possible." />
3
- <c:p t:content="Thank you!" />
1
+ <c:p t:content="formSubmitted" />
2
+ <c:p t:content="formSubmittedInfo" />
3
+ <c:p t:content="thankYou" />
4
4
  <% if (!page.noLinks) { %>
5
5
  <c:list type="unstyled" margin="start-3">
6
- <c:list-item t:content="Goto Home" href="/" icon="house"/>
6
+ <c:list-item t:content="gotoHome" href="/" icon="house"/>
7
7
  </c:list>
8
8
  <% } %>
@@ -1,11 +1,11 @@
1
1
  <% if (_meta.user) { %>
2
- <c:list-item href="sumba:/my-stuff/profile" t:content="Your Profile" />
3
- <c:list-item href="sumba:/my-stuff/change-password" t:content="Change Password" />
2
+ <c:list-item href="sumba:/my-stuff/profile" t:content="yourProfile" />
3
+ <c:list-item href="sumba:/my-stuff/change-password" t:content="changePassword" />
4
4
  <% if (attr.withSignout) { %>
5
- <c:list-item href="sumba:/signout" t:content="Signout" />
5
+ <c:list-item href="sumba:/signout" t:content="signout" />
6
6
  <% } %>
7
7
  <% } else { %>
8
- <c:list-item href="sumba:/signin" t:content="Signin" />
9
- <c:list-item href="sumba:/user/signup" t:content="New User Signup" />
10
- <c:list-item href="sumba:/user/forgot-password" t:content="Forgot Password" />
8
+ <c:list-item href="sumba:/signin" t:content="signin" />
9
+ <c:list-item href="sumba:/user/signup" t:content="signup" />
10
+ <c:list-item href="sumba:/user/forgot-password" t:content="forgotPassword" />
11
11
  <% } %>
@@ -1 +1 @@
1
- <c:list-item t:content="Your Profile" href="sumba:/my-stuff/profile" icon="person"/>
1
+ <c:list-item t:content="yourProfile" href="sumba:/my-stuff/profile" icon="person"/>
@@ -0,0 +1,12 @@
1
+ <c:grid-row>
2
+ <c:grid-col col="6-md">
3
+ <c:form button reset-validation referer>
4
+ <c:form-password name="currentPassword" label-floating wrapper-margin="bottom-2" />
5
+ <c:form-password name="newPassword" label-floating wrapper-margin="bottom-2" />
6
+ <c:form-password name="verifyNewPassword" label-floating wrapper-margin="bottom-3" />
7
+ </c:form>
8
+ </c:grid-col>
9
+ <c:grid-col col="6-md">
10
+
11
+ </c:grid-col>
12
+ </c:grid-row>
@@ -0,0 +1,50 @@
1
+ <c:form referer>
2
+ <c:grid-row>
3
+ <c:grid-col col="8-md">
4
+ <c:fieldset t:legend="meta" grid-gutter="2" margin="bottom-3">
5
+ <c:form-plaintext name="createdAt" label-floating col="6-md"/>
6
+ <c:form-plaintext name="updatedAt" label-floating col="6-md"/>
7
+ </c:fieldset>
8
+ <c:fieldset t:legend="account" grid-gutter="2" margin="bottom-3">
9
+ <c:form-plaintext name="username" label-floating col="6-lg"/>
10
+ <c:form-input name="email" label-floating col="6-lg"/>
11
+ <c:form-input name="firstName" label-floating col="6-lg"/>
12
+ <c:form-input name="lastName" label-floating col="6-lg"/>
13
+ </c:fieldset>
14
+ <c:fieldset t:legend="address" grid-gutter="2">
15
+ <c:form-input name="address1" label-floating col="12"/>
16
+ <c:form-input name="address2" label-floating col="12"/>
17
+ <c:form-input name="city" label-floating col="8-lg 7-md"/>
18
+ <c:form-input name="zipCode" label-floating col="4-lg 5-md"/>
19
+ <c:form-input name="provinceState" label-floating col="6-lg"/>
20
+ <c:form-select-country name="country" label-floating col="6-lg"/>
21
+ <c:form-input name="phone" label-floating col="6-lg"/>
22
+ <c:form-input name="website" label-floating col="6-lg"/>
23
+ </c:fieldset>
24
+ </c:grid-col>
25
+ <c:grid-col col="4-md">
26
+ <c:heading type="5" t:content="image" />
27
+ <c:img holder="400x200" responsive rounded />
28
+ <c:form-file name="image" no-label wrapper-margin="top-2"/>
29
+ <c:btn-group margin="top-3" flex="full">
30
+ <c:btn type="reset" t:content="reset" color="secondary" />
31
+ <c:btn type="submit" t:content="submit" color="primary" />
32
+ </c:btn-group>
33
+ <% if (arguments[0].error) { %>
34
+ <c:btn x-data @click="wbs.invalidateForm" href="#" icon="remove" color="link" size="sm" margin="top-2">
35
+ <c:t>clearInvalidFields</c:t>
36
+ </c:btn>
37
+ <% } %>
38
+ <hr />
39
+ <c:heading type="5" t:content="more" margin="top-3" />
40
+ <c:list type="group" hover>
41
+ <c:list-item href="sumba:/my-stuff/change-password" t:content="changePassword" />
42
+ <c:list-item t:content="displayApiKey" target="api-key-modal"/>
43
+ </c:list>
44
+ <c:list type="unstyled" margin="top-3">
45
+ <c:list-item href="sumba:/my-stuff/profile" t:content="backToProfile" icon="arrowStart" />
46
+ </c:list>
47
+ <c:include resource="sumba.partial:/api-key-modal.html" />
48
+ </c:grid-col>
49
+ </c:grid-row>
50
+ </c:form>
@@ -0,0 +1,34 @@
1
+ <c:grid-row gutter="4">
2
+ <c:grid-col col="8-md">
3
+ <c:fieldset t:legend="meta" grid-gutter="2" margin="bottom-3">
4
+ <c:form-plaintext name="createdAt" label-floating col="6-md"/>
5
+ <c:form-plaintext name="updatedAt" label-floating col="6-md"/>
6
+ </c:fieldset>
7
+ <c:fieldset t:legend="account" grid-gutter="2" margin="bottom-3">
8
+ <c:form-plaintext name="username" label-floating col="6-lg"/>
9
+ <c:form-plaintext name="email" label-floating col="6-lg"/>
10
+ <c:form-plaintext name="firstName" label-floating col="6-lg"/>
11
+ <c:form-plaintext name="lastName" label-floating col="6-lg"/>
12
+ </c:fieldset>
13
+ <c:fieldset t:legend="address" grid-gutter="2">
14
+ <c:form-plaintext name="address1" label-floating col="12"/>
15
+ <c:form-plaintext name="address2" label-floating col="12"/>
16
+ <c:form-plaintext name="city" label-floating col="8-lg 7-md"/>
17
+ <c:form-plaintext name="zipCode" label-floating col="4-lg 5-md"/>
18
+ <c:form-plaintext name="provinceState" label-floating col="6-lg"/>
19
+ <c:form-plaintext name="country" label-floating col="6-lg"/>
20
+ <c:form-plaintext name="phone" label-floating col="6-lg"/>
21
+ <c:form-plaintext name="website" label-floating col="6-lg"/>
22
+ </c:fieldset>
23
+ </c:grid-col>
24
+ <c:grid-col col="4-md">
25
+ <c:heading type="5" t:content="image" />
26
+ <c:img holder="400x200" responsive rounded />
27
+ <c:heading type="5" t:content="more" margin="top-3" />
28
+ <c:list type="group" hover>
29
+ <c:list-item href="sumba:/my-stuff/profile/edit" t:content="updateProfile" />
30
+ <c:list-item t:content="displayApiKey" target="api-key-modal"/>
31
+ </c:list>
32
+ <c:include resource="sumba.partial:/api-key-modal.html" />
33
+ </c:grid-col>
34
+ </c:grid-row>
@@ -0,0 +1,12 @@
1
+ <c:form button reset-validation>
2
+ <c:form-plaintext name="apiKey" label-floating wrapper-margin="bottom-2" />
3
+ <c:form-password name="password" label-floating wrapper-margin="bottom-3" />
4
+ </c:form>
5
+ <% if (!page.noLinks) { %>
6
+ <c:list type="unstyled" margin="start-3">
7
+ <c:include resource="sumba.partial:/list-item/your-profile.html" />
8
+ <c:include resource="sumba.partial:/list-item/change-password.html" />
9
+ <c:include resource="sumba.partial:/list-item/signout.html" />
10
+ <c:include resource="sumba.partial:/list-item/goto-home.html" />
11
+ </c:list>
12
+ <% } %>
@@ -1,7 +1,7 @@
1
1
  <c:p t:content="signoutWarning" />
2
2
  <c:form method="POST" action="sumba:/signout" referer>
3
- <c:btn color="primary" t:content="Yes, sign me out now!" type="submit" />
3
+ <c:btn color="primary" t:content="signoutNow" type="submit" />
4
4
  <% if (!page.noLinks) { %>
5
- <c:btn color="link" icon="house" t:content="Goto Home" href="/" />
5
+ <c:btn color="link" icon="house" t:content="gotoHome" href="/" />
6
6
  <% } %>
7
7
  </c:form>
@@ -0,0 +1,10 @@
1
+ <c:form button reset-validation referer>
2
+ <c:form-input name="key" label-floating />
3
+ </c:form>
4
+ <% if (!page.noLinks) { %>
5
+ <c:list type="unstyled" margin="start-3">
6
+ <c:include resource="sumba.partial:/list-item/signin.html" />
7
+ <c:include resource="sumba.partial:/list-item/forgot-password.html" />
8
+ <c:include resource="sumba.partial:/list-item/goto-home.html" />
9
+ </c:list>
10
+ <% } %>
@@ -0,0 +1,10 @@
1
+ <c:form button reset-validation>
2
+ <c:form-input name="usernameEmail" label-floating wrapper-margin="bottom-2" t:hint="linkPasswordWillbeSent"/>
3
+ </c:form>
4
+ <% if (!page.noLinks) { %>
5
+ <c:list type="unstyled" margin="start-3">
6
+ <c:include resource="sumba.partial:/list-item/signin.html" />
7
+ <c:include resource="sumba.partial:/list-item/user-signup.html" />
8
+ <c:include resource="sumba.partial:/list-item/goto-home.html" />
9
+ </c:list>
10
+ <% } %>
@@ -0,0 +1,16 @@
1
+ <c:form button reset-validation referer grid-gutter="2">
2
+ <c:form-input name="username" label-floating />
3
+ <c:form-password name="password" col="6-lg" label-floating />
4
+ <c:form-password name="verifyPassword" col="6-lg" label-floating />
5
+ <c:form-input type="email" name="email" label-floating />
6
+ <c:form-input name="firstName" col="6-lg" label-floating />
7
+ <c:form-input name="lastName" col="6-lg" label-floating />
8
+ <c:form-check name="agree" col="12" value="true" t:label="agreeToTerm%s%s|<%= _routePath('sumba:/info/terms-conditions') %>|termsConditions" />
9
+ </c:form>
10
+ <% if (!page.noLinks) { %>
11
+ <c:list type="unstyled" margin="start-3">
12
+ <c:include resource="sumba.partial:/list-item/forgot-password.html" />
13
+ <c:include resource="sumba.partial:/list-item/signin.html" />
14
+ <c:include resource="sumba.partial:/list-item/goto-home.html" />
15
+ </c:list>
16
+ <% } %>
@@ -0,0 +1,8 @@
1
+ <c:p t:content="formSubmitted" />
2
+ <c:p t:content="formSubmittedInfo" />
3
+ <c:p t:content="thankYou" />
4
+ <% if (!page.noLinks) { %>
5
+ <c:list type="unstyled" margin="start-3">
6
+ <c:list-item t:content="gotoHome" href="/" icon="house"/>
7
+ </c:list>
8
+ <% } %>
@@ -21,15 +21,15 @@ const profile = {
21
21
  try {
22
22
  await schema.validateAsync(req.body, this.app.dobo.config.validationParams)
23
23
  } catch (err) {
24
- throw this.error('Validation Error', { details: err.details, values: err.values, ns: this.name, statusCode: 422, code: 'DB_VALIDATION' })
24
+ throw this.error('validationError', { details: err.details, values: err.values, ns: this.name, statusCode: 422, code: 'DB_VALIDATION' })
25
25
  }
26
26
  const rec = await recordGet(model, req.user.id)
27
27
  const verified = await bcrypt.compare(req.body.currentPassword, rec.password)
28
- if (!verified) throw this.error('Invalid current password', { details: [{ field: 'currentPassword', error: 'Invalid password' }], statusCode: 400 })
28
+ if (!verified) throw this.error('invalidCurrentPassword', { details: [{ field: 'currentPassword', error: 'invalidPassword' }], statusCode: 400 })
29
29
  await recordUpdate(model, req.user.id, { password: req.body.newPassword })
30
30
  // signout and redirect to signin
31
31
  req.session.user = null
32
- req.flash('notify', req.t('You\'ve successfully changed your password. Now please re-signin with your new password'))
32
+ req.flash('notify', req.t('passwordChangedReSignin'))
33
33
  return reply.redirectTo('sumba:/signin')
34
34
  } catch (err) {
35
35
  error = err
@@ -17,7 +17,7 @@ const profile = {
17
17
  } else {
18
18
  const resp = await recordUpdate({ req, model: 'SumbaUser', id: req.user.id, body: form, options: { noFlash: true, hidden: [] } })
19
19
  form = resp.data
20
- req.flash('notify', req.t('Your profile is successfully updated'))
20
+ req.flash('notify', req.t('profileUpdated'))
21
21
  }
22
22
  } catch (err) {
23
23
  console.log(err)
@@ -18,14 +18,14 @@ const resetApiKey = {
18
18
  try {
19
19
  await schema.validateAsync(req.body, this.app.dobo.config.validationParams)
20
20
  } catch (err) {
21
- throw this.error('Validation Error', { details: err.details, values: err.values, ns: this.name, statusCode: 422, code: 'DB_VALIDATION' })
21
+ throw this.error('validationError', { details: err.details, values: err.values, ns: this.name, statusCode: 422, code: 'DB_VALIDATION' })
22
22
  }
23
23
  const rec = await recordGet(model, req.user.id)
24
24
  const verified = await bcrypt.compare(req.body.password, rec.password)
25
- if (!verified) throw this.error('Validation Error', { details: [{ field: 'password', error: 'Invalid password' }], statusCode: 400 })
25
+ if (!verified) throw this.error('validationError', { details: [{ field: 'password', error: 'invalidPassword' }], statusCode: 400 })
26
26
  await recordUpdate(model, req.user.id, { token: generateId() })
27
27
  await delay(2000) // ensure req.user cache is expired
28
- req.flash('notify', req.t('You\'ve successfully reset your Api Key'))
28
+ req.flash('notify', req.t('resetApiKeySuccessfull'))
29
29
  return reply.redirectTo('sumba:/profile')
30
30
  } catch (err) {
31
31
  error = err
@@ -19,7 +19,7 @@ const signin = {
19
19
  await runHook(`${this.name}:afterSignin`, user, sid, req)
20
20
  const { query, params } = req
21
21
  const url = !isEmpty(referer) ? referer : this.config.redirect.afterSignin
22
- req.flash('notify', req.t('You\'ve successfully signed in!'))
22
+ req.flash('notify', req.t('signinSuccessfully'))
23
23
  return reply.redirectTo(url, { query, params })
24
24
  } catch (err) {
25
25
  error = err
@@ -12,12 +12,12 @@ const signout = {
12
12
  const sid = await getSessionId(req.headers.cookie)
13
13
  const user = req.session.user
14
14
  req.session.user = null
15
- if (this.bajoEmitter) await this.app.bajoEmitter.emit(`${this.name}.sigout`, user, sid)
15
+ if (this.bajoEmitter) await this.app.bajoEmitter.emit(`${this.name}.signout`, user, sid)
16
16
  await runHook(`${this.name}:afterSignout`, user, sid, req)
17
17
  const { query, params } = req
18
18
  // const url = !isEmpty(referer) ? referer : this.config.redirect.home
19
19
  const url = this.config.redirect.afterSignout
20
- req.flash('notify', req.t('You\'ve successfully signed out!'))
20
+ req.flash('notify', req.t('signoutSuccessfully'))
21
21
  return reply.redirectTo(url, { query, params })
22
22
  }
23
23
  return reply.view('sumba.template:/signout.html', { form: { referer } })
@@ -9,9 +9,9 @@ const userActivation = {
9
9
  try {
10
10
  const query = { status: 'UNVERIFIED', token: req.body.key }
11
11
  const result = await recordFind('SumbaUser', { query }, { noHook: true })
12
- if (result.length === 0) throw this.error('Validation Error', { details: [{ field: 'key', error: 'Invalid activation key' }] })
12
+ if (result.length === 0) throw this.error('validationError', { details: [{ field: 'key', error: 'invalidActivationKey' }] })
13
13
  await recordUpdate('SumbaUser', result[0].id, { status: 'ACTIVE' }, { noHook: true, noValidation: true, noFlash: true })
14
- req.flash('notify', req.t('User account successfully activated'))
14
+ req.flash('notify', req.t('userActivated'))
15
15
  return reply.redirectTo(this.config.redirect.signin, req)
16
16
  } catch (err) {
17
17
  error = err
@@ -23,7 +23,7 @@ const signup = {
23
23
  const validation = { ns: ['sumba', 'dobo'], fields, extFields }
24
24
  req.body.token = generateId()
25
25
  const { data } = await recordCreate({ model: 'SumbaUser', req, reply, options: { validation, noFlash: true } })
26
- req.flash('notify', 'User account successfully created')
26
+ req.flash('notify', 'userCreated')
27
27
  return reply.view('sumba.template:/user/signup/success.html', { form: req.body, data })
28
28
  } catch (err) {
29
29
  error = err
@@ -1,5 +1,4 @@
1
1
  ---
2
- t:title: Contact Form
2
+ t:title: contactForm
3
3
  layout: sumba.layout:/wide.html
4
4
  ---
5
- <c:include resource="sumba.partial:/help/contact-form/form.html" />
@@ -1,5 +1,4 @@
1
1
  ---
2
- t:title: Contact Form
2
+ t:title: contactForm
3
3
  layout: sumba.layout:/wide.html
4
4
  ---
5
- <c:include resource="sumba.partial:/help/contact-form/success.html" />
@@ -1,5 +1,4 @@
1
1
  ---
2
- t:title: Trouble Tickets
2
+ t:title: troubleTickets
3
3
  layout: sumba.layout:/wide.html
4
4
  ---
5
- <c:include resource="sumba.partial:/help/trouble-tickets/list.html" />
@@ -1,5 +1,4 @@
1
1
  ---
2
2
  layout: sumba.layout:/info.html
3
- title: Wakakak
3
+ title: aboutUs
4
4
  ---
5
- idddd
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: sumba.layout:/info.html
3
- t:title: About Us
3
+ t:title: aboutUs
4
4
  ---
5
5
  Dolore aliqua excepteur consequat sint anim eiusmod aliqua ex in. Consequat velit officia ipsum ut proident magna laborum aliqua irure quis tempor dolor. Lorem duis duis sint adipisicing do in mollit cillum proident nisi adipisicing dolor. Excepteur mollit eu cillum aute aliquip laboris incididunt officia dolore qui quis cupidatat anim amet. Voluptate labore consequat esse culpa ea. Aliqua cupidatat excepteur non laborum enim minim.
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: sumba.layout:/info.html
3
- t:title: Cookie Policy
3
+ t:title: cookiePolicy
4
4
  ---
5
5
  Last updated: January 31, 2025
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: sumba.layout:/info.html
3
- t:title: Privacy Statement
3
+ t:title: privacyStatement
4
4
  ---
5
5
  Last updated: January 31, 2025
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: sumba.layout:/info.html
3
- t:title: Terms and Conditions
3
+ t:title: termsConditions
4
4
  ---
5
5
  Last updated: January 31, 2025
6
6
 
@@ -1,16 +1,4 @@
1
1
  ---
2
- t:title: Change Password
2
+ t:title: changePassword
3
3
  layout: sumba.layout:/wide.html
4
4
  ---
5
- <c:grid-row>
6
- <c:grid-col col="6-md">
7
- <c:form button reset-validation referer>
8
- <c:form-password name="currentPassword" label-floating wrapper-margin="bottom-2" />
9
- <c:form-password name="newPassword" label-floating wrapper-margin="bottom-2" />
10
- <c:form-password name="verifyNewPassword" label-floating wrapper-margin="bottom-3" />
11
- </c:form>
12
- </c:grid-col>
13
- <c:grid-col col="6-md">
14
-
15
- </c:grid-col>
16
- </c:grid-row>
@@ -1,56 +1,6 @@
1
1
  ---
2
- t:title: Edit Your Profile
2
+ t:title: editYourProfile
3
3
  layout: sumba.layout:/wide.html
4
4
  scripts:
5
5
  - waibuExtra.virtual:/holderjs/holder.min.js
6
6
  ---
7
- <c:form referer>
8
- <c:grid-row>
9
- <c:grid-col col="8-md">
10
- <c:fieldset t:legend="Meta" grid-gutter="2" margin="bottom-3">
11
- <c:form-plaintext name="createdAt" label-floating col="6-md"/>
12
- <c:form-plaintext name="updatedAt" label-floating col="6-md"/>
13
- </c:fieldset>
14
- <c:fieldset t:legend="Account" grid-gutter="2" margin="bottom-3">
15
- <c:form-plaintext name="username" label-floating col="6-lg"/>
16
- <c:form-input name="email" label-floating col="6-lg"/>
17
- <c:form-input name="firstName" label-floating col="6-lg"/>
18
- <c:form-input name="lastName" label-floating col="6-lg"/>
19
- </c:fieldset>
20
- <c:fieldset t:legend="Address" grid-gutter="2">
21
- <c:form-input name="address1" label-floating col="12"/>
22
- <c:form-input name="address2" label-floating col="12"/>
23
- <c:form-input name="city" label-floating col="8-lg 7-md"/>
24
- <c:form-input name="zipCode" label-floating col="4-lg 5-md"/>
25
- <c:form-input name="provinceState" label-floating col="6-lg"/>
26
- <c:form-select-country name="country" label-floating col="6-lg"/>
27
- <c:form-input name="phone" label-floating col="6-lg"/>
28
- <c:form-input name="website" label-floating col="6-lg"/>
29
- </c:fieldset>
30
- </c:grid-col>
31
- <c:grid-col col="4-md">
32
- <c:heading type="5" t:content="Image" />
33
- <c:img holder="400x200" responsive rounded />
34
- <c:form-file name="image" no-label wrapper-margin="top-2"/>
35
- <c:btn-group margin="top-3" flex="full">
36
- <c:btn type="reset" t:content="Reset" color="secondary" />
37
- <c:btn type="submit" t:content="Submit" color="primary" />
38
- </c:btn-group>
39
- <% if (arguments[0].error) { %>
40
- <c:btn x-data @click="wbs.invalidateForm" href="#" icon="remove" color="link" size="sm" margin="top-2">
41
- <c:t>Clear Invalid Fields</c:t>
42
- </c:btn>
43
- <% } %>
44
- <hr />
45
- <c:heading type="5" t:content="More" margin="top-3" />
46
- <c:list type="group" hover>
47
- <c:list-item href="sumba:/my-stuff/change-password" t:content="Change Password" />
48
- <c:list-item t:content="Display API Key" target="api-key-modal"/>
49
- </c:list>
50
- <c:list type="unstyled" margin="top-3">
51
- <c:list-item href="sumba:/my-stuff/profile" t:content="Back to Profile" icon="arrowStart" />
52
- </c:list>
53
- <c:include resource="sumba.partial:/api-key-modal.html" />
54
- </c:grid-col>
55
- </c:grid-row>
56
- </c:form>
@@ -1,40 +1,6 @@
1
1
  ---
2
- t:title: Your Profile
2
+ t:title: yourProfile
3
3
  layout: sumba.layout:/wide.html
4
4
  scripts:
5
5
  - waibuExtra.virtual:/holderjs/holder.min.js
6
6
  ---
7
- <c:grid-row gutter="4">
8
- <c:grid-col col="8-md">
9
- <c:fieldset t:legend="Meta" grid-gutter="2" margin="bottom-3">
10
- <c:form-plaintext name="createdAt" label-floating col="6-md"/>
11
- <c:form-plaintext name="updatedAt" label-floating col="6-md"/>
12
- </c:fieldset>
13
- <c:fieldset t:legend="Account" grid-gutter="2" margin="bottom-3">
14
- <c:form-plaintext name="username" label-floating col="6-lg"/>
15
- <c:form-plaintext name="email" label-floating col="6-lg"/>
16
- <c:form-plaintext name="firstName" label-floating col="6-lg"/>
17
- <c:form-plaintext name="lastName" label-floating col="6-lg"/>
18
- </c:fieldset>
19
- <c:fieldset t:legend="Address" grid-gutter="2">
20
- <c:form-plaintext name="address1" label-floating col="12"/>
21
- <c:form-plaintext name="address2" label-floating col="12"/>
22
- <c:form-plaintext name="city" label-floating col="8-lg 7-md"/>
23
- <c:form-plaintext name="zipCode" label-floating col="4-lg 5-md"/>
24
- <c:form-plaintext name="provinceState" label-floating col="6-lg"/>
25
- <c:form-plaintext name="country" label-floating col="6-lg"/>
26
- <c:form-plaintext name="phone" label-floating col="6-lg"/>
27
- <c:form-plaintext name="website" label-floating col="6-lg"/>
28
- </c:fieldset>
29
- </c:grid-col>
30
- <c:grid-col col="4-md">
31
- <c:heading type="5" t:content="Image" />
32
- <c:img holder="400x200" responsive rounded />
33
- <c:heading type="5" t:content="More" margin="top-3" />
34
- <c:list type="group" hover>
35
- <c:list-item href="sumba:/my-stuff/profile/edit" t:content="Update Profile" />
36
- <c:list-item t:content="Display API Key" target="api-key-modal"/>
37
- </c:list>
38
- <c:include resource="sumba.partial:/api-key-modal.html" />
39
- </c:grid-col>
40
- </c:grid-row>
@@ -1,16 +1,4 @@
1
1
  ---
2
- t:title: Reset API Key
2
+ t:title: resetApiKey
3
3
  layout: sumba.layout:/wide.html
4
4
  ---
5
- <c:form button reset-validation>
6
- <c:form-plaintext name="apiKey" label-floating wrapper-margin="bottom-2" />
7
- <c:form-password name="password" label-floating wrapper-margin="bottom-3" />
8
- </c:form>
9
- <% if (!page.noLinks) { %>
10
- <c:list type="unstyled" margin="start-3">
11
- <c:include resource="sumba.partial:/list-item/your-profile.html" />
12
- <c:include resource="sumba.partial:/list-item/change-password.html" />
13
- <c:include resource="sumba.partial:/list-item/signout.html" />
14
- <c:include resource="sumba.partial:/list-item/goto-home.html" />
15
- </c:list>
16
- <% } %>
@@ -1,3 +1,3 @@
1
1
  ---
2
- t:title: Signin
2
+ t:title: signin
3
3
  ---
@@ -1,3 +1,3 @@
1
1
  ---
2
- t:title: Signout
2
+ t:title: signout
3
3
  ---
@@ -1,13 +1,3 @@
1
1
  ---
2
- t:title: User Activation
2
+ t:title: userActivation
3
3
  ---
4
- <c:form button reset-validation referer>
5
- <c:form-input name="key" label-floating />
6
- </c:form>
7
- <% if (!page.noLinks) { %>
8
- <c:list type="unstyled" margin="start-3">
9
- <c:include resource="sumba.partial:/list-item/signin.html" />
10
- <c:include resource="sumba.partial:/list-item/forgot-password.html" />
11
- <c:include resource="sumba.partial:/list-item/goto-home.html" />
12
- </c:list>
13
- <% } %>
@@ -1,13 +1,3 @@
1
1
  ---
2
- t:title: Forgot Password
2
+ t:title: forgotPassword
3
3
  ---
4
- <c:form button reset-validation>
5
- <c:form-input name="usernameEmail" label-floating wrapper-margin="bottom-2" t:hint="Link to reset password wil be sent to your email"/>
6
- </c:form>
7
- <% if (!page.noLinks) { %>
8
- <c:list type="unstyled" margin="start-3">
9
- <c:include resource="sumba.partial:/list-item/signin.html" />
10
- <c:include resource="sumba.partial:/list-item/user-signup.html" />
11
- <c:include resource="sumba.partial:/list-item/goto-home.html" />
12
- </c:list>
13
- <% } %>
@@ -1,19 +1,3 @@
1
1
  ---
2
- t:title: New User Signup
2
+ t:title: newUserSignup
3
3
  ---
4
- <c:form button reset-validation referer grid-gutter="2">
5
- <c:form-input name="username" label-floating />
6
- <c:form-password name="password" col="6-lg" label-floating />
7
- <c:form-password name="verifyPassword" col="6-lg" label-floating />
8
- <c:form-input type="email" name="email" label-floating />
9
- <c:form-input name="firstName" col="6-lg" label-floating />
10
- <c:form-input name="lastName" col="6-lg" label-floating />
11
- <c:form-check name="agree" col="12" value="true" t:label="I agree to the <a href='../info/terms-conditions'>Terms and Conditions</a>" />
12
- </c:form>
13
- <% if (!page.noLinks) { %>
14
- <c:list type="unstyled" margin="start-3">
15
- <c:include resource="sumba.partial:/list-item/forgot-password.html" />
16
- <c:include resource="sumba.partial:/list-item/signin.html" />
17
- <c:include resource="sumba.partial:/list-item/goto-home.html" />
18
- </c:list>
19
- <% } %>
@@ -1,11 +1,3 @@
1
1
  ---
2
- t:title: New User Signup
2
+ t:title: newUserSignup
3
3
  ---
4
- <c:p t:content="Form submitted successfully!" />
5
- <c:p t:content="Please allow us to read your submission thoroughly and we'll get back to you rightaway" />
6
- <c:p t:content="Thank you!" />
7
- <% if (!page.noLinks) { %>
8
- <c:list type="unstyled" margin="start-3">
9
- <c:list-item t:content="Goto Home" href="/" icon="house"/>
10
- </c:list>
11
- <% } %>
@@ -42,7 +42,7 @@ async function update ({ ctx }) {
42
42
  const handler = async function get (req, reply, options) {
43
43
  const rec = await recordGet(model, req.user.id)
44
44
  const verified = await bcrypt.compare(req.body.currentPassword, rec.password)
45
- if (!verified) throw this.error('Invalid current password', { details: [{ field: 'current', error: 'Invalid password' }], statusCode: 400 })
45
+ if (!verified) throw this.error('invalidCurrentPassword', { details: [{ field: 'current', error: 'invalidPassword' }], statusCode: 400 })
46
46
  const input = { password: req.body.password }
47
47
  await recordUpdate(model, req.user.id, input)
48
48
  return {}
@@ -16,7 +16,7 @@ async function create () {
16
16
  const { hash } = this.app.bajoExtra
17
17
  const { getUserFromUsernamePassword, createJwtFromUserRecord } = this
18
18
 
19
- if (!['api-key', 'jwt', 'apiKey'].includes(req.params.type)) throw this.error('Invalid token type')
19
+ if (!['api-key', 'jwt', 'apiKey'].includes(req.params.type)) throw this.error('invalidTokenType')
20
20
  const rec = await getUserFromUsernamePassword(req.body.username, req.body.password, req)
21
21
  if (req.params.type === 'jwt') {
22
22
  const jwt = await createJwtFromUserRecord(rec)
@@ -1,11 +0,0 @@
1
- {
2
- "signoutWarning": "You\\'re about to sign out. This means your session will be cleared and you\\'ll be asked for your credential again in case you want to access any protected pages and resources.<br /><br />Are your sure?",
3
- "field": {
4
- "currentPassword": "Current Password",
5
- "newPassword": "New Password",
6
- "verifyNewPassword": "Verify New Password",
7
- "usernameEmail": "Username/Email",
8
- "subject": "Subject",
9
- "message": "Message"
10
- }
11
- }
@@ -1,78 +0,0 @@
1
- {
2
- "Invalid api key provided": "",
3
- "User is inactive or temporarily disabled": "",
4
- "Invalid token or token is expired": "",
5
- "Unknown username": "Nama pengguna tidak dikenal",
6
- "Invalid password": "Kata kunci tidak valid",
7
- "Unknown site or site is not configured yet": "",
8
- "This site is currently inactive or disabled. Please contact your admin, thanks!": "",
9
- "No authentication method found. Please contact your admin immediately!": "",
10
- "Invalid authentication method '%s'": "",
11
- "Access denied. Can't authenticate you through all available methods": "",
12
- "Invalid token type": "",
13
- "Invalid current password": "",
14
- "Theme support is globally disabled!": "",
15
- "Theme '%s' is not installed": "",
16
- "Profile": "Profil",
17
- "Your Profile": "Profil Anda",
18
- "Edit Your Profile": "Ubah Profil Anda",
19
- "Account": "Akun",
20
- "Address": "Alamat",
21
- "Phone/Email": "Telpon/Surel",
22
- "Change Password": "Ganti Kata Sandi",
23
- "Signout": "Keluar",
24
- "Signin": "Masuk",
25
- "Your Stuff": "Perkakas Anda",
26
- "Forgot Password": "Lupa Kata Sandi",
27
- "User Activation": "Aktivasi Pengguna",
28
- "New User Signup": "Pendaftaran Pengguna",
29
- "Update Profile": "Perbarui Profil",
30
- "Back to Profile": "Kembali ke Profil",
31
- "Display API Key": "Tampilkan Kunci API",
32
- "API Key": "Kunci API",
33
- "About Us": "Tentang Kami",
34
- "Terms": "Ketentuan",
35
- "Privacy": "Privasi",
36
- "Invalid activation key": "Kunci aktivasi invalid",
37
- "Yes, sign me out now!": "Ya, keluarkan saya sekarang!",
38
- "signoutWarning": "Anda akan keluar. Ini berarti sesi Anda akan dihapus dan Anda akan ditanyakan kembali kredensial Anda jika Anda akan mengakses halaman-halaman yang diproteksi.<br /><br />Anda yakin?",
39
- "Clear Invalid Fields": "Bersihkan Kolom Invalid",
40
- "Link to reset password wil be sent to your email": "Tautan untuk mengubah kata sandi akan dikirim ke surel Anda",
41
- "You've successfully signed in!": "Anda sukses melakukan login",
42
- "You've successfully signed out!": "Anda sukses melakukan logout",
43
- "Your profile is successfully updated": "Profil Anda sukses diperbarui",
44
- "You've successfully changed your password. Now please re-signin with your new password": "Anda sukses melakukan perbaruan kata kunci. Sekarang silahkan melakukan login ulang dengan kata kunci baru Anda",
45
- "I agree to the <a href='./info/terms-conditions'>Terms and Conditions</a>": "Saya setuju dengan semua <a href='./info/terms-conditions'>Ketentuan dan Persyaratan</a>",
46
- "User account successfully activated": "Akun pengguna sukses diaktivasi",
47
- "User account successfully created": "Akun pengguna sukses dibuat",
48
- "Reset API Key": "Reset Kunci API",
49
- "Person In Charge": "Penanggung Jawab",
50
- "Contact Form": "Form Kontak",
51
- "All rights reserved": "Hak cipta dilindungi Undang-undang",
52
- "Terms & Conditions": "Term & Kondisi",
53
- "Cookie Policy": "Kebijakan Cookie",
54
- "Privacy Statement": "Pernyataan Privasi",
55
- "Legal Info": "Info Legal",
56
- "Help": "Bantuan",
57
- "Trouble Tickets": "Tiket Masalah",
58
- "field": {
59
- "currentPassword": "Kata Sandi Saat Ini",
60
- "newPassword": "Kata Sandi Baru",
61
- "verifyPassword": "Verifikasi Kata Sandi",
62
- "verifyNewPassword": "Verifikasi Sandi Baru",
63
- "usernameEmail": "Nama Pengguna/Surel",
64
- "apiKey": "Kunci API",
65
- "hostname": "Nama Host",
66
- "iconset": "Iconset",
67
- "subject": "Judul",
68
- "message": "Pesan"
69
- },
70
- "validation": {
71
- "password.minOfUppercase": "Mengandung setidaknya {{min}} huruf besar",
72
- "password.minOfSpecialCharacters": "Mengandung setidaknya {{min}} karakter spesial",
73
- "password.minOfLowercase": "Mengandung setidaknya {{min}} huruf kecil",
74
- "password.minOfNumeric": "Mengandung setidaknya {{min}} numerik/angka",
75
- "password.noWhiteSpaces": "Tidak boleh ada spasi",
76
- "password.onlyLatinCharacters": "Harus berupa karakter latin saja"
77
- }
78
- }