diff --git a/.gitignore b/.gitignore index 31dc553..fd6e947 100644 --- a/.gitignore +++ b/.gitignore @@ -33,5 +33,4 @@ go.work.sum .run # temporary -coworker/ webapp/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5406cdf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM golang:1.22-alpine AS builder +WORKDIR /build + +COPY go.mod go.sum ./ +RUN go mod download && go mod verify + +COPY cmd/backend cmd/backend +COPY pkg pkg +COPY internal internal + +RUN GOEXPERIMENT=boringcrypto go build -ldflags "-s -w" -o ./app ./cmd/backend +RUN chmod +x ./app + +FROM alpine:3.21.2 AS production +WORKDIR /backend + +COPY --from=builder /build/app . +COPY cmd/backend/config.yaml . +COPY cmd/backend/jwt_signing_key . + +EXPOSE 8080 + +CMD ["./app", "-c", "config.yaml"] \ No newline at end of file diff --git a/cmd/coworker/config.yaml b/cmd/coworker/config.yaml new file mode 100644 index 0000000..4bb1b89 --- /dev/null +++ b/cmd/coworker/config.yaml @@ -0,0 +1,11 @@ +app: + serviceUrl: "https://localhost:8080" +kafka: + brokers: + - localhost:9092 + topic: backend_events +smtp: + server: smtp.yandex.ru + port: 587 + email: "" + password: "" \ No newline at end of file diff --git a/cmd/coworker/main.go b/cmd/coworker/main.go new file mode 100644 index 0000000..a9ca104 --- /dev/null +++ b/cmd/coworker/main.go @@ -0,0 +1,130 @@ +package main + +import ( + "backend/pkg/logger" + "context" + "encoding/json" + "fmt" + "io" + "log" + "os" + "strings" + + "github.com/segmentio/kafka-go" + "gopkg.in/gomail.v2" + "gopkg.in/yaml.v3" +) + +const MSG_TEXT = ` + +
+ + +This message was sent because you forgot a password
+ + + +` + +func SendEmailForgotPassword(dialer *gomail.Dialer, from, to, link string) error { + msgText := strings.ReplaceAll(MSG_TEXT, "{{Link}}", link) + + m := gomail.NewMessage() + m.SetHeader("From", m.FormatAddress(from, "Pet Backend")) + m.SetHeader("To", to) + m.SetHeader("Subject", "Hello!") + m.SetBody("text/html", msgText) + + return dialer.DialAndSend(m) +} + +type Config struct { + App struct { + LogFile string `yaml:"logFile"` + ServiceUrl string `yaml:"serviceUrl"` + } + + Kafka struct { + Brokers []string `yaml:"brokers"` + Topic string `yaml:"topic"` + ConsumerGroupId string `yaml:"consumerGroupId"` + } `yaml:"kafka"` + + SMTP struct { + Server string `yaml:"server"` + Port int `yaml:"port"` + Email string `yaml:"email"` + Password string `yaml:"password"` + } `yaml:"smtp"` +} + +func main() { + ctx := context.Background() + + configFile, err := os.ReadFile("config.yaml") + if err != nil { + log.Fatal(err.Error()) + } + + config := &Config{} + if err := yaml.Unmarshal(configFile, config); err != nil { + log.Fatal(err.Error()) + } + + dialer := gomail.NewDialer(config.SMTP.Server, config.SMTP.Port, config.SMTP.Email, config.SMTP.Password) + + r := kafka.NewReader(kafka.ReaderConfig{ + Brokers: config.Kafka.Brokers, + Topic: config.Kafka.Topic, + GroupID: config.Kafka.ConsumerGroupId, + }) + + logger, err := logger.New( + ctx, + logger.NewLoggerOpts{ + Debug: true, + OutputFile: config.App.LogFile, + }, + ) + if err != nil { + log.Fatal(err.Error()) + } + + logger.Printf("coworker service started\n") + + for { + msg, err := r.FetchMessage(ctx) + if err == io.EOF { + log.Fatal("EOF") + return + } + if err != nil { + log.Fatal(err.Error()) + return + } + + log.Printf("offset: %d, partition: %d, key: %s, value: %s\n", msg.Offset, msg.Partition, string(msg.Key), string(msg.Value)) + + if err := r.CommitMessages(ctx, msg); err != nil { + log.Fatalf("failed to commit: %s\n", err.Error()) + continue + } + + value := struct { + Email string `json:"email"` + Token string `json:"token"` + }{} + + if err := json.Unmarshal(msg.Value, &value); err != nil { + log.Fatalf("failed to unmarshal: %s\n", err.Error()) + continue + } + + link := fmt.Sprintf("%s/restore-password?token=%s", config.App.ServiceUrl, value.Token) + + if err := SendEmailForgotPassword(dialer, config.SMTP.Email, value.Email, link); err != nil { + log.Fatalf("failed to send email: %s\n", err.Error()) + continue + } + } +} diff --git a/docker-compose.yaml b/docker-compose.yaml index 8dfad49..cfbd7ea 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,6 +1,6 @@ services: postgres: - image: postgres:16.4 + image: postgres:16.4-alpine shm_size: 256mb command: | postgres diff --git a/dockerfile b/dockerfile deleted file mode 100644 index daf5c37..0000000 --- a/dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM golang:1.22 - -WORKDIR /usr/src/app - -COPY go.mod go.sum ./ -RUN go mod download && go mod verify - -EXPOSE 8080 - -COPY . . -RUN go build -v -o ./app . -RUN chmod +x ./app - -CMD ["./app", "-c", "./misc/config.yaml"] \ No newline at end of file