Skip to content
quarry Artifact [8b7c17640d]
Login

Artifact [8b7c17640d]

Artifact 8b7c17640d77a95f9214dec7e697a4a7998b2b41b3934fb6b6231e6c63e7d1d2:


package api

import (
	"context"
	"encoding/json"
	"strings"
	"testing"

	"craftdesign.group/quarry/internal/ops"
)

var inviteToken = strings.Repeat("cd", 32)

type inviteAccounts struct{ *resetAccounts }

func (f inviteAccounts) InviteAccount(string, string, bool) (string, error) { return inviteToken, nil }

// #319: an invite that went to the invitee's own address is theirs.
// The admin learns that it went, and does not get a copy of the link.
func TestAnEmailedInviteIsNotHandedToTheAdmin(t *testing.T) {
	accts := inviteAccounts{&resetAccounts{fakeAccounts: newFakeAccounts()}}
	_ = accts.AddAccount("root", "root-password", true)
	mail := &textMail{}
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Accounts: accts, Mail: mail, Origin: "https://forge.example"}); err != nil {
		t.Fatal(err)
	}
	ctx := ops.WithUser(context.Background(), "root")

	out, err := r.Invoke(ctx, "account.invite", accountInviteIn{Name: "bob", Email: "[email protected]"})
	if err != nil {
		t.Fatal(err)
	}
	if len(mail.sent) != 1 || !strings.Contains(mail.sent[0].Text, inviteToken) {
		t.Fatalf("FAIL: the invitee was not mailed the link: %+v", mail.sent)
	}
	wire, _ := json.Marshal(out)
	var got map[string]any
	_ = json.Unmarshal(wire, &got)
	if got["emailed"] != true {
		t.Errorf("FAIL: emailed = %v", got["emailed"])
	}
	if strings.Contains(string(wire), inviteToken) {
		t.Errorf("FAIL: the emailed invite's token came back to the admin: %s", wire)
	}

	// With no address there is nobody else to send it to: the admin
	// hands it over, and it only works while the account is unclaimed.
	out, err = r.Invoke(ctx, "account.invite", accountInviteIn{Name: "carol"})
	if err != nil {
		t.Fatal(err)
	}
	wire, _ = json.Marshal(out)
	got = nil
	_ = json.Unmarshal(wire, &got)
	if got["link"] != "https://forge.example/invite/"+inviteToken {
		t.Errorf("FAIL: an invite with no address did not return its link: %s", wire)
	}
	t.Log("ok: emailed invite withholds the link; unaddressed invite returns it")
}