Skip to content

Commit

Permalink
🔄 Sync from monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
mojo-machine[bot] committed Dec 12, 2023
1 parent f770df9 commit 4ed12c2
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 31 deletions.
6 changes: 4 additions & 2 deletions lib/discourse/roundtripper.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ type roundTripper struct {
header http.Header
}

func (h roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
func (r roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
req = req.Clone(req.Context())

if req.Header == nil {
req.Header = http.Header{}
}

for k, v := range h.header {
for k, v := range r.header {
req.Header[k] = v
}

Expand Down
92 changes: 92 additions & 0 deletions lib/googleiid/googleiid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package googleiid

import (
"context"
"time"

"github.com/wearemojo/mojo-public-go/lib/errgroup"
"github.com/wearemojo/mojo-public-go/lib/httpclient"
"github.com/wearemojo/mojo-public-go/lib/jsonclient"
"github.com/wearemojo/mojo-public-go/lib/secret"
)

const baseURL = "https://iid.googleapis.com"

type Client struct {
client *jsonclient.Client
}

func NewClient(ctx context.Context, serverKeySecretID, vapidPublicKeySecretID string) (*Client, error) {
g := errgroup.WithContext(ctx)

g.Go(func(ctx context.Context) (err error) {
_, err = secret.Get(ctx, serverKeySecretID)
return
})

g.Go(func(ctx context.Context) (err error) {
_, err = secret.Get(ctx, vapidPublicKeySecretID)
return
})

if err := g.Wait(); err != nil {
return nil, err
}

return &Client{
client: jsonclient.NewClient(
baseURL,
httpclient.NewClient(5*time.Second, roundTripper{
ServerKeySecretID: serverKeySecretID,
VAPIDPublicKeySecretID: vapidPublicKeySecretID,
}),
),
}, nil
}

type APNSRequest struct {
Application string `json:"application"`
Sandbox bool `json:"sandbox"`
APNSTokens []string `json:"apns_tokens"`
}

type APNSResponse struct {
// order does not relate to the request ordering - match by token
Results []APNSResponseResult `json:"results"`
}

type APNSResponseResult struct {
RegistrationToken string `json:"registration_token"`
APNSToken string `json:"apns_token"`
Status string `json:"status"`
}

func (r APNSResponseResult) Valid() bool {
// we've also noticed `INVALID_ARGUMENT` and `INTERNAL` on the status field
return r.Status == "OK" && r.APNSToken != "" && r.RegistrationToken != ""
}

type WebPushRequest struct {
Endpoint string `json:"endpoint"`

Keys WebPushRequestKeys `json:"keys"`
}

type WebPushRequestKeys struct {
Auth string `json:"auth"`
P256DH string `json:"p256dh"`
}

type WebPushResponse struct {
Token string `json:"token"`
}

func (c *Client) ImportAPNSTokens(ctx context.Context, req *APNSRequest) (res *APNSResponse, err error) {
// https://web.archive.org/web/20220407013020/https://developers.google.com/instance-id/reference/server#create_registration_tokens_for_apns_tokens
return res, c.client.Do(ctx, "POST", "iid/v1:batchImport", nil, req, &res)
}

func (c *Client) ImportWebPushSubscription(ctx context.Context, req *WebPushRequest) (res *WebPushResponse, err error) {
// https://web.archive.org/web/20220407013020/https://developers.google.com/instance-id/reference/server#import_push_subscriptions
return res, c.client.Do(ctx, "POST", "v1/web/iid", nil, req, &res)
}
50 changes: 50 additions & 0 deletions lib/googleiid/roundtripper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package googleiid

import (
"context"
"net/http"

"github.com/wearemojo/mojo-public-go/lib/errgroup"
"github.com/wearemojo/mojo-public-go/lib/secret"
)

type roundTripper struct {
ServerKeySecretID string
VAPIDPublicKeySecretID string
}

func (r roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
ctx := req.Context()
req = req.Clone(ctx)

var serverKey string
var vapidPublicKey string

g := errgroup.WithContext(ctx)

g.Go(func(ctx context.Context) (err error) {
serverKey, err = secret.Get(ctx, r.ServerKeySecretID)
return
})

g.Go(func(ctx context.Context) (err error) {
vapidPublicKey, err = secret.Get(ctx, r.VAPIDPublicKeySecretID)
return
})

if err := g.Wait(); err != nil {
return nil, err
}

if req.Header == nil {
req.Header = http.Header{}
}

// https://web.archive.org/web/20221206045856/https://firebase.google.com/docs/cloud-messaging/auth-server#authorize-http-requests
req.Header.Set("Authorization", "key="+serverKey)

// https://developers.google.com/instance-id/reference/server#parameters_5
req.Header.Set("Crypto-Key", "p256ecdsa="+vapidPublicKey)

return http.DefaultTransport.RoundTrip(req)
}
36 changes: 10 additions & 26 deletions lib/postmark/client.go → lib/postmark/postmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/wearemojo/mojo-public-go/lib/secret"
)

const baseURL = "https://api.postmarkapp.com"

//nolint:tagliatelle // postmark uses title case
type Response struct {
To string `json:"To"`
Expand All @@ -32,42 +34,24 @@ type EmailWithTemplate struct {
}

type Client struct {
BaseURL string

secretID string
client *jsonclient.Client
}

func NewClient(ctx context.Context, baseURL, secretID string) (*Client, error) {
if _, err := secret.Get(ctx, secretID); err != nil {
func NewClient(ctx context.Context, serverTokenSecretID string) (*Client, error) {
if _, err := secret.Get(ctx, serverTokenSecretID); err != nil {
return nil, err
}

return &Client{
BaseURL: baseURL,

secretID: secretID,
client: jsonclient.NewClient(
baseURL,
httpclient.NewClient(5*time.Second, roundTripper{serverTokenSecretID}),
),
}, nil
}

func (c *Client) client(ctx context.Context) (*jsonclient.Client, error) {
apiKey, err := secret.Get(ctx, c.secretID)
if err != nil {
return nil, err
}

return jsonclient.NewClient(
c.BaseURL,
httpclient.NewClient(5*time.Second, roundTripper{apiKey}),
), nil
}

func (c *Client) SendWithTemplate(ctx context.Context, req *EmailWithTemplate) (res *Response, err error) {
jsonClient, err := c.client(ctx)
if err != nil {
return nil, err
}

err = jsonClient.Do(ctx, "POST", "email/withTemplate", nil, req, &res)
err = c.client.Do(ctx, "POST", "email/withTemplate", nil, req, &res)
if cerr, ok := gerrors.As[cher.E](err); ok {
cerr.Code = fmt.Sprintf("postmark_%s", cerr.Code)
return nil, cerr
Expand Down
16 changes: 13 additions & 3 deletions lib/postmark/roundtripper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@ package postmark

import (
"net/http"

"github.com/wearemojo/mojo-public-go/lib/secret"
)

type roundTripper struct {
serverToken string
SecretID string
}

func (h roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
func (r roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
ctx := req.Context()
req = req.Clone(ctx)

serverToken, err := secret.Get(ctx, r.SecretID)
if err != nil {
return nil, err
}

if req.Header == nil {
req.Header = http.Header{}
}

req.Header.Set("X-Postmark-Server-Token", h.serverToken)
req.Header.Set("X-Postmark-Server-Token", serverToken)

return http.DefaultTransport.RoundTrip(req)
}

0 comments on commit 4ed12c2

Please sign in to comment.