Skip to content

Commit

Permalink
add smtp encrypt type and 418 for april
Browse files Browse the repository at this point in the history
  • Loading branch information
zyxkad committed Mar 27, 2024
1 parent 7ad38cc commit 33ad5cb
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 10 deletions.
5 changes: 5 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ notification:
enable-email: false
# 邮件 SMTP 服务器及其端口
email-smtp: smtp.example.com:25
# SMTP 服务器加密类型
# - none : 无加密
# - ssl : 使用 SSL/TLS 加密
# - tls : 使用 STARTTLS 加密
email-smtp-encryption: tls
# 通知者邮箱用户名
email-sender: noreply@example.com
# 通知者邮箱密码
Expand Down
5 changes: 4 additions & 1 deletion cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,10 @@ func (cr *Cluster) Init(ctx context.Context) (err error) {
webpushPlg := new(webpush.Plugin)
cr.notifyManager.AddPlugin(webpushPlg)
if config.Notification.EnableEmail {
emailPlg, err := email.NewSMTP(config.Notification.EmailSMTP, config.Notification.EmailSender, config.Notification.EmailSenderPassword)
emailPlg, err := email.NewSMTP(
config.Notification.EmailSMTP, config.Notification.EmailSMTPEncryption,
config.Notification.EmailSender, config.Notification.EmailSenderPassword,
)
if err != nil {
return err
}
Expand Down
13 changes: 13 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type APIRateLimitConfig struct {
type NotificationConfig struct {
EnableEmail bool `yaml:"enable-email"`
EmailSMTP string `yaml:"email-smtp"`
EmailSMTPEncryption string `yaml:"email-smtp-encryption"`
EmailSender string `yaml:"email-sender"`
EmailSenderPassword string `yaml:"email-sender-password"`
EnableWebhook bool `yaml:"enable-webhook"`
Expand Down Expand Up @@ -212,6 +213,9 @@ type Config struct {
Storages []storage.StorageOption `yaml:"storages"`
WebdavUsers map[string]*storage.WebDavUser `yaml:"webdav-users"`
Advanced AdvancedConfig `yaml:"advanced"`

IamTeaPot bool `yaml:"i-am-a-tea-pot"`
TeapotMessages []string `yaml:"teapot-messages"`
}

func (cfg *Config) applyWebManifest(manifest map[string]any) {
Expand Down Expand Up @@ -277,6 +281,7 @@ var defaultConfig = Config{
Notification: NotificationConfig{
EnableEmail: false,
EmailSMTP: "smtp.example.com:25",
EmailSMTPEncryption: "tls",
EmailSender: "noreply@example.com",
EmailSenderPassword: "example-password",
EnableWebhook: true,
Expand Down Expand Up @@ -326,6 +331,14 @@ var defaultConfig = Config{
NoFastEnable: false,
WaitBeforeEnable: 0,
},

IamTeaPot: false,
TeapotMessages: []string{
"This is OpemBnclApi golang edition",
"Your internet is shutdown",
"Virus detected, removing your game data ...",
":)",
},
}

func migrateConfig(data []byte, config *Config) {
Expand Down
1 change: 1 addition & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ api-rate-limit:
notification:
enable-email: false
email-smtp: smtp.example.com:25
email-smtp-encryption: tls
email-sender: noreply@example.com
email-sender-password: example-password
enable-webhook: true
Expand Down
18 changes: 14 additions & 4 deletions dashboard/src/api/v0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,27 @@ export async function getSubscribePublicKey(token?: string): Promise<string> {
return res.data.publicKey
}

export type SubscribeScope = 'enabled' | 'disabled' | 'syncdone' | 'updates' | 'dailyreport'
export type SubscribeScope =
| 'enabled'
| 'disabled'
| 'syncbegin'
| 'syncdone'
| 'updates'
| 'dailyreport'
export const ALL_SUBSCRIBE_SCOPES: SubscribeScope[] = [
'enabled',
'disabled',
'syncbegin',
'syncdone',
'updates',
'dailyreport',
]
export type ScopeFlags = {
[key in SubscribeScope]: boolean
}

export interface SubscribeSettings {
scopes: { [key in SubscribeScope]: boolean }
scopes: ScopeFlags
reportAt: string
}

Expand Down Expand Up @@ -219,7 +229,7 @@ export interface EmailItemPayload {
export interface EmailItemRes {
user: string
addr: string
scopes: SubscribeScope[]
scopes: ScopeFlags
enabled: boolean
}

Expand Down Expand Up @@ -281,7 +291,7 @@ export interface WebhookItemRes {
name: string
endpoint: string
authHash?: string
scopes: SubscribeScope[]
scopes: ScopeFlags
enabled: boolean
}

Expand Down
5 changes: 5 additions & 0 deletions dashboard/src/views/SettingsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const settings = bindObjectToLocalStorage(
{
notifyWhenDisabled: false,
notifyWhenEnabled: false,
notifyWhenSyncBegin: false,
notifyWhenSyncFinished: false,
notifyUpdates: false,
dailyReport: false,
Expand Down Expand Up @@ -68,6 +69,9 @@ function getSubscribeScopes(): SubscribeScope[] {
if (settings.notifyWhenEnabled) {
res.push('enabled')
}
if (settings.notifyWhenSyncBegin) {
res.push('syncbegin')
}
if (settings.notifyWhenSyncFinished) {
res.push('syncdone')
}
Expand Down Expand Up @@ -183,6 +187,7 @@ onMounted(() => {
enableNotify.value = true
settings.notifyWhenDisabled = sets.scopes.disabled
settings.notifyWhenEnabled = sets.scopes.enabled
settings.notifyWhenSyncBegin = sets.scopes.syncbegin
settings.notifyWhenSyncFinished = sets.scopes.syncdone
settings.notifyUpdates = sets.scopes.updates
settings.dailyReport = sets.scopes.dailyreport
Expand Down
20 changes: 17 additions & 3 deletions dashboard/src/views/settings/NotificationsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
updateWebhook,
removeWebhook,
type SubscribeScope,
type ScopeFlags,
type EmailItemPayload,
type EmailItemRes,
type WebhookItemPayload,
Expand Down Expand Up @@ -57,7 +58,12 @@ const webhookEdited = computed((): boolean => {
return true
}
}
if (ori.scopes.join() !== item.scopes.join()) {
if (
(Object.keys(ori.scopes) as SubscribeScope[])
.map((v) => ori.scopes[v])
.sort()
.join() !== item.scopes.sort().join()
) {
return true
}
if (item.auth !== '-') {
Expand Down Expand Up @@ -117,6 +123,7 @@ async function addEmail(item: EmailItemPayload): Promise<void> {
emails.value?.push({
user: '',
...item,
scopes: Object.fromEntries(item.scopes.map((v) => [v, true])) as ScopeFlags,
})
} catch (err) {
toast.add({
Expand Down Expand Up @@ -184,9 +191,16 @@ async function openRemoveWebhookDialog(index: number): Promise<void> {
}
}
function scopeFlagsToArray(o: ScopeFlags): SubscribeScope[] {
return (Object.keys(o) as SubscribeScope[])
.filter((v) => o[v])
.sort()
}
function openWebhookEditDialog(item: WebhookItemRes): void {
webhookEditingItem.value = {
...item,
scopes: scopeFlagsToArray(item.scopes),
auth: '-',
_: item,
}
Expand Down Expand Up @@ -328,7 +342,7 @@ onBeforeMount(() => {
</Column>
<Column
:header="tr('title.webhook.scopes')"
:field="({ scopes }) => scopes.join(', ')"
:field="({ scopes }) => scopeFlagsToArray(scopes).join(', ')"
style="flex-shrink: 0; width: 10rem"
>
<template #footer>
Expand Down Expand Up @@ -449,7 +463,7 @@ onBeforeMount(() => {
<div class="flex-row-center text-overflow-ellipsis">
<label class="webhook-edit-label">{{ tr('title.webhook.scopes') }}:</label>
<span class="flex-auto text-nowrap text-overflow-ellipsis">{{
item.scopes.join(', ')
scopeFlagsToArray(item.scopes).join(', ')
}}</span>
</div>
</template>
Expand Down
51 changes: 51 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"os"
"strconv"
"strings"
"sync"
"time"

"github.com/LiterMC/go-openbmclapi/internal/build"
Expand Down Expand Up @@ -327,6 +328,9 @@ var emptyHashes = func() (hashes map[string]struct{}) {

var HeaderXPoweredBy = fmt.Sprintf("go-openbmclapi/%s; url=https://github.com/LiterMC/go-openbmclapi", build.BuildVersion)

var accessedTeapotMux sync.RWMutex
var accessedTeapot = make(map[string]struct{})

func (cr *Cluster) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
method := req.Method
u := req.URL
Expand All @@ -342,6 +346,53 @@ func (cr *Cluster) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
return
}

/** TODO: remove after 04/01 **/
if config.IamTeaPot {
ip, _ := req.Context().Value(RealAddrCtxKey).(string)
if ip != "" {
_, month, day := time.Now().Date()
if month == time.April && day == 1 || month == time.March && day == 31 || month == time.March && day == 32 {
ua, _, _ := strings.Cut(req.Header.Get("User-Agent"), " ")
ua, _, _ = strings.Cut(ua, "/")
chance := 0
switch ua {
case "HMCL":
chance = 512
case "PCL":
chance = 511
case "PojavLauncher":
chance = 512 * 10
case "FCL":
fallthrough
case "BakaXL":
chance = 512 * 2
}
if chance > 0 {
if randIntn(1024000) < chance/2 {
accessedTeapotMux.RLock()
_, ok := accessedTeapot[ip]
accessedTeapotMux.RUnlock()
if !ok {
accessedTeapotMux.Lock()
if _, ok = accessedTeapot[ip]; !ok {
accessedTeapot[ip] = struct{}{}
}
accessedTeapotMux.Unlock()
if !ok {
var msg string = "okay, this is a teapot, however, you will never saw this again"
if len(config.TeapotMessages) > 0 {
msg = config.TeapotMessages[randIntn(len(config.TeapotMessages))]
}
http.Error(rw, msg, http.StatusTeapot)
return
}
}
}
}
}
}
}

hash := rawpath[len("/download/"):]
if !utils.IsHex(hash) {
http.Error(rw, hash+" is not a valid hash", http.StatusNotFound)
Expand Down
14 changes: 12 additions & 2 deletions notify/email/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"html/template"
"net"
"strconv"
"strings"
"time"

mail "github.com/xhit/go-simple-mail/v2"
Expand Down Expand Up @@ -64,16 +65,25 @@ type Plugin struct {

var _ notify.Plugin = (*Plugin)(nil)

func NewSMTP(smtpAddr string, username string, password string) (*Plugin, error) {
func NewSMTP(smtpAddr string, smtpType string, username string, password string) (*Plugin, error) {
smtp := &mail.SMTPServer{
Authentication: mail.AuthAuto,
Encryption: mail.EncryptionSTARTTLS,
Helo: "localhost",
ConnectTimeout: 15 * time.Second,
SendTimeout: time.Minute,
Username: username,
Password: password,
}
switch strings.ToLower(smtpType) {
case "tls", "starttls":
smtp.Encryption = mail.EncryptionSTARTTLS
case "ssl", "ssltls":
smtp.Encryption = mail.EncryptionSSLTLS
case "none":
smtp.Encryption = mail.EncryptionNone
default:
return nil, fmt.Errorf("Unknown smtp encryption type %q", smtpType)
}
var (
port string
err error
Expand Down

0 comments on commit 33ad5cb

Please sign in to comment.