mirror of
https://github.com/fiatjaf/nak.git
synced 2025-12-22 14:38:51 +00:00
dekey: add logs.
This commit is contained in:
37
dekey.go
37
dekey.go
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"fiatjaf.com/nostr"
|
"fiatjaf.com/nostr"
|
||||||
"fiatjaf.com/nostr/nip44"
|
"fiatjaf.com/nostr/nip44"
|
||||||
|
"github.com/fatih/color"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,11 +31,13 @@ var dekey = &cli.Command{
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
|
log(color.CyanString("gathering keyer from arguments...\n"))
|
||||||
kr, _, err := gatherKeyerFromArguments(ctx, c)
|
kr, _, err := gatherKeyerFromArguments(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(color.CyanString("getting user public key...\n"))
|
||||||
userPub, err := kr.GetPublicKey(ctx)
|
userPub, err := kr.GetPublicKey(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get user public key: %w", err)
|
return fmt.Errorf("failed to get user public key: %w", err)
|
||||||
@@ -43,32 +46,40 @@ var dekey = &cli.Command{
|
|||||||
configPath := c.String("config-path")
|
configPath := c.String("config-path")
|
||||||
deviceName := c.String("device-name")
|
deviceName := c.String("device-name")
|
||||||
|
|
||||||
|
log(color.YellowString("handling device key for %s...\n"), deviceName)
|
||||||
// check if we already have a local-device secret key
|
// check if we already have a local-device secret key
|
||||||
deviceKeyPath := filepath.Join(configPath, "dekey", "device-key")
|
deviceKeyPath := filepath.Join(configPath, "dekey", "device-key")
|
||||||
var deviceSec nostr.SecretKey
|
var deviceSec nostr.SecretKey
|
||||||
if data, err := os.ReadFile(deviceKeyPath); err == nil {
|
if data, err := os.ReadFile(deviceKeyPath); err == nil {
|
||||||
|
log(color.GreenString("found existing device key\n"))
|
||||||
deviceSec, err = nostr.SecretKeyFromHex(string(data))
|
deviceSec, err = nostr.SecretKeyFromHex(string(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid device key in %s: %w", deviceKeyPath, err)
|
return fmt.Errorf("invalid device key in %s: %w", deviceKeyPath, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
log(color.YellowString("generating new device key...\n"))
|
||||||
// create one
|
// create one
|
||||||
deviceSec = nostr.Generate()
|
deviceSec = nostr.Generate()
|
||||||
os.MkdirAll(filepath.Dir(deviceKeyPath), 0700)
|
os.MkdirAll(filepath.Dir(deviceKeyPath), 0700)
|
||||||
if err := os.WriteFile(deviceKeyPath, []byte(deviceSec.Hex()), 0600); err != nil {
|
if err := os.WriteFile(deviceKeyPath, []byte(deviceSec.Hex()), 0600); err != nil {
|
||||||
return fmt.Errorf("failed to write device key: %w", err)
|
return fmt.Errorf("failed to write device key: %w", err)
|
||||||
}
|
}
|
||||||
|
log(color.GreenString("device key generated and stored\n"))
|
||||||
}
|
}
|
||||||
devicePub := deviceSec.Public()
|
devicePub := deviceSec.Public()
|
||||||
|
|
||||||
// get relays for the user
|
// get relays for the user
|
||||||
|
log(color.CyanString("fetching write relays for user...\n"))
|
||||||
relays := sys.FetchWriteRelays(ctx, userPub)
|
relays := sys.FetchWriteRelays(ctx, userPub)
|
||||||
|
log(color.CyanString("connecting to %d relays...\n"), len(relays))
|
||||||
relayList := connectToAllRelays(ctx, c, relays, nil, nostr.PoolOptions{})
|
relayList := connectToAllRelays(ctx, c, relays, nil, nostr.PoolOptions{})
|
||||||
if len(relayList) == 0 {
|
if len(relayList) == 0 {
|
||||||
return fmt.Errorf("no relays to use")
|
return fmt.Errorf("no relays to use")
|
||||||
}
|
}
|
||||||
|
log(color.GreenString("connected to %d relays\n"), len(relayList))
|
||||||
|
|
||||||
// check if kind:4454 is already published
|
// check if kind:4454 is already published
|
||||||
|
log(color.CyanString("checking for existing device registration (kind:4454)...\n"))
|
||||||
events := sys.Pool.FetchMany(ctx, relays, nostr.Filter{
|
events := sys.Pool.FetchMany(ctx, relays, nostr.Filter{
|
||||||
Kinds: []nostr.Kind{4454},
|
Kinds: []nostr.Kind{4454},
|
||||||
Authors: []nostr.PubKey{userPub},
|
Authors: []nostr.PubKey{userPub},
|
||||||
@@ -77,6 +88,7 @@ var dekey = &cli.Command{
|
|||||||
},
|
},
|
||||||
}, nostr.SubscriptionOptions{Label: "nak-nip4e"})
|
}, nostr.SubscriptionOptions{Label: "nak-nip4e"})
|
||||||
if len(events) == 0 {
|
if len(events) == 0 {
|
||||||
|
log(color.YellowString("no device registration found, publishing kind:4454...\n"))
|
||||||
// publish kind:4454
|
// publish kind:4454
|
||||||
evt := nostr.Event{
|
evt := nostr.Event{
|
||||||
Kind: 4454,
|
Kind: 4454,
|
||||||
@@ -97,9 +109,13 @@ var dekey = &cli.Command{
|
|||||||
if err := publishFlow(ctx, c, kr, evt, relayList); err != nil {
|
if err := publishFlow(ctx, c, kr, evt, relayList); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log(color.GreenString("device registration published\n"))
|
||||||
|
} else {
|
||||||
|
log(color.GreenString("device already registered\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for kind:10044
|
// check for kind:10044
|
||||||
|
log(color.CyanString("checking for user encryption key (kind:10044)...\n"))
|
||||||
userKeyEventDate := nostr.Now()
|
userKeyEventDate := nostr.Now()
|
||||||
userKeyResult := sys.Pool.FetchManyReplaceable(ctx, relays, nostr.Filter{
|
userKeyResult := sys.Pool.FetchManyReplaceable(ctx, relays, nostr.Filter{
|
||||||
Kinds: []nostr.Kind{10044},
|
Kinds: []nostr.Kind{10044},
|
||||||
@@ -108,6 +124,7 @@ var dekey = &cli.Command{
|
|||||||
var eSec nostr.SecretKey
|
var eSec nostr.SecretKey
|
||||||
var ePub nostr.PubKey
|
var ePub nostr.PubKey
|
||||||
if userKeyEvent, ok := userKeyResult.Load(nostr.ReplaceableKey{PubKey: userPub, D: ""}); !ok {
|
if userKeyEvent, ok := userKeyResult.Load(nostr.ReplaceableKey{PubKey: userPub, D: ""}); !ok {
|
||||||
|
log(color.YellowString("no user encryption key found, generating new one...\n"))
|
||||||
// generate main secret key
|
// generate main secret key
|
||||||
eSec = nostr.Generate()
|
eSec = nostr.Generate()
|
||||||
ePub := eSec.Public()
|
ePub := eSec.Public()
|
||||||
@@ -118,8 +135,10 @@ var dekey = &cli.Command{
|
|||||||
if err := os.WriteFile(eKeyPath, []byte(eSec.Hex()), 0600); err != nil {
|
if err := os.WriteFile(eKeyPath, []byte(eSec.Hex()), 0600); err != nil {
|
||||||
return fmt.Errorf("failed to write user encryption key: %w", err)
|
return fmt.Errorf("failed to write user encryption key: %w", err)
|
||||||
}
|
}
|
||||||
|
log(color.GreenString("user encryption key generated and stored\n"))
|
||||||
|
|
||||||
// publish kind:10044
|
// publish kind:10044
|
||||||
|
log(color.YellowString("publishing user encryption key (kind:10044)...\n"))
|
||||||
evt10044 := nostr.Event{
|
evt10044 := nostr.Event{
|
||||||
Kind: 10044,
|
Kind: 10044,
|
||||||
Content: "",
|
Content: "",
|
||||||
@@ -135,7 +154,9 @@ var dekey = &cli.Command{
|
|||||||
if err := publishFlow(ctx, c, kr, evt10044, relayList); err != nil {
|
if err := publishFlow(ctx, c, kr, evt10044, relayList); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log(color.GreenString("user encryption key published\n"))
|
||||||
} else {
|
} else {
|
||||||
|
log(color.GreenString("found existing user encryption key\n"))
|
||||||
userKeyEventDate = userKeyEvent.CreatedAt
|
userKeyEventDate = userKeyEvent.CreatedAt
|
||||||
|
|
||||||
// get the pub from the tag
|
// get the pub from the tag
|
||||||
@@ -152,6 +173,7 @@ var dekey = &cli.Command{
|
|||||||
// check if we have the key
|
// check if we have the key
|
||||||
eKeyPath := filepath.Join(configPath, "dekey", "e", ePub.Hex())
|
eKeyPath := filepath.Join(configPath, "dekey", "e", ePub.Hex())
|
||||||
if data, err := os.ReadFile(eKeyPath); err == nil {
|
if data, err := os.ReadFile(eKeyPath); err == nil {
|
||||||
|
log(color.GreenString("found stored user encryption key\n"))
|
||||||
eSec, err = nostr.SecretKeyFromHex(string(data))
|
eSec, err = nostr.SecretKeyFromHex(string(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid main key: %w", err)
|
return fmt.Errorf("invalid main key: %w", err)
|
||||||
@@ -160,6 +182,7 @@ var dekey = &cli.Command{
|
|||||||
return fmt.Errorf("stored user encryption key is corrupted: %w", err)
|
return fmt.Errorf("stored user encryption key is corrupted: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
log(color.YellowString("user encryption key not stored locally, attempting to decrypt from other devices...\n"))
|
||||||
// try to decrypt from kind:4455
|
// try to decrypt from kind:4455
|
||||||
for eKeyMsg := range sys.Pool.FetchMany(ctx, relays, nostr.Filter{
|
for eKeyMsg := range sys.Pool.FetchMany(ctx, relays, nostr.Filter{
|
||||||
Kinds: []nostr.Kind{4455},
|
Kinds: []nostr.Kind{4455},
|
||||||
@@ -191,6 +214,7 @@ var dekey = &cli.Command{
|
|||||||
}
|
}
|
||||||
// check if it matches mainPub
|
// check if it matches mainPub
|
||||||
if eSec.Public() == ePub {
|
if eSec.Public() == ePub {
|
||||||
|
log(color.GreenString("successfully decrypted user encryption key from another device\n"))
|
||||||
// store it
|
// store it
|
||||||
os.MkdirAll(filepath.Dir(eKeyPath), 0700)
|
os.MkdirAll(filepath.Dir(eKeyPath), 0700)
|
||||||
os.WriteFile(eKeyPath, []byte(eSecHex), 0600)
|
os.WriteFile(eKeyPath, []byte(eSecHex), 0600)
|
||||||
@@ -201,11 +225,13 @@ var dekey = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if eSec == [32]byte{} {
|
if eSec == [32]byte{} {
|
||||||
log("main secret key not available, must authorize on another device\n")
|
log(color.RedString("main secret key not available, must authorize on another device\n"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
log(color.GreenString("user encryption key ready\n"))
|
||||||
|
|
||||||
// now we have mainSec, check for other kind:4454 events newer than the 10044
|
// now we have mainSec, check for other kind:4454 events newer than the 10044
|
||||||
|
log(color.CyanString("checking for other devices and key messages...\n"))
|
||||||
keyMsgs := make([]string, 0, 5)
|
keyMsgs := make([]string, 0, 5)
|
||||||
for keyOrDeviceEvt := range sys.Pool.FetchMany(ctx, relays, nostr.Filter{
|
for keyOrDeviceEvt := range sys.Pool.FetchMany(ctx, relays, nostr.Filter{
|
||||||
Kinds: []nostr.Kind{4454, 4455},
|
Kinds: []nostr.Kind{4454, 4455},
|
||||||
@@ -214,6 +240,7 @@ var dekey = &cli.Command{
|
|||||||
}, nostr.SubscriptionOptions{Label: "nak-nip4e"}) {
|
}, nostr.SubscriptionOptions{Label: "nak-nip4e"}) {
|
||||||
if keyOrDeviceEvt.Kind == 4455 {
|
if keyOrDeviceEvt.Kind == 4455 {
|
||||||
// key event
|
// key event
|
||||||
|
log(color.BlueString("received key message (kind:4455)\n"))
|
||||||
|
|
||||||
// skip ourselves
|
// skip ourselves
|
||||||
if keyOrDeviceEvt.Tags.FindWithValue("p", devicePub.Hex()) != nil {
|
if keyOrDeviceEvt.Tags.FindWithValue("p", devicePub.Hex()) != nil {
|
||||||
@@ -229,6 +256,7 @@ var dekey = &cli.Command{
|
|||||||
keyMsgs = append(keyMsgs, pubkeyTag[1])
|
keyMsgs = append(keyMsgs, pubkeyTag[1])
|
||||||
} else if keyOrDeviceEvt.Kind == 4454 {
|
} else if keyOrDeviceEvt.Kind == 4454 {
|
||||||
// device event
|
// device event
|
||||||
|
log(color.BlueString("received device registration (kind:4454)\n"))
|
||||||
|
|
||||||
// skip ourselves
|
// skip ourselves
|
||||||
if keyOrDeviceEvt.Tags.FindWithValue("pubkey", devicePub.Hex()) != nil {
|
if keyOrDeviceEvt.Tags.FindWithValue("pubkey", devicePub.Hex()) != nil {
|
||||||
@@ -246,6 +274,7 @@ var dekey = &cli.Command{
|
|||||||
|
|
||||||
// here we know we're dealing with a deviceMsg without a corresponding keyMsg
|
// here we know we're dealing with a deviceMsg without a corresponding keyMsg
|
||||||
// so we have to build a keyMsg for them
|
// so we have to build a keyMsg for them
|
||||||
|
log(color.YellowString("sending encryption key to new device...\n"))
|
||||||
theirDevice, err := nostr.PubKeyFromHex(pubkeyTag[1])
|
theirDevice, err := nostr.PubKeyFromHex(pubkeyTag[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@@ -273,7 +302,11 @@ var dekey = &cli.Command{
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
publishFlow(ctx, c, kr, evt4455, relayList)
|
if err := publishFlow(ctx, c, kr, evt4455, relayList); err != nil {
|
||||||
|
log(color.RedString("failed to publish key message: %v\n"), err)
|
||||||
|
} else {
|
||||||
|
log(color.GreenString("encryption key sent to device\n"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user