Compare commits
8 commits
f46461c886
...
8445a7546e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8445a7546e | |||
| c041a5feee | |||
| 7ddf1162c7 | |||
| a8a11ed86e | |||
| 39f7e63c72 | |||
| 5bb0a76d61 | |||
| d79d141986 | |||
| 8a56431b8f |
17 changed files with 296 additions and 36 deletions
99
.dockerignore
Normal file
99
.dockerignore
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# flyctl launch added from .gitignore
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/vim,linux,macos,go
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,linux,macos,go
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
**/*.exe
|
||||||
|
**/*.exe~
|
||||||
|
**/*.dll
|
||||||
|
**/*.so
|
||||||
|
**/*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
**/*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
**/*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
**/go.work
|
||||||
|
|
||||||
|
### Linux ###
|
||||||
|
**/*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
**/.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
**/.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
**/.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
**/.nfs*
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
**/.DS_Store
|
||||||
|
**/.AppleDouble
|
||||||
|
**/.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
**/Icon
|
||||||
|
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
**/._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
**/.DocumentRevisions-V100
|
||||||
|
**/.fseventsd
|
||||||
|
**/.Spotlight-V100
|
||||||
|
**/.TemporaryItems
|
||||||
|
**/.Trashes
|
||||||
|
**/.VolumeIcon.icns
|
||||||
|
**/.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
**/.AppleDB
|
||||||
|
**/.AppleDesktop
|
||||||
|
**/Network Trash Folder
|
||||||
|
**/Temporary Items
|
||||||
|
**/.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
**/*.icloud
|
||||||
|
|
||||||
|
### Vim ###
|
||||||
|
# Swap
|
||||||
|
**/[._]*.s[a-v][a-z]
|
||||||
|
!**/*.svg # comment out if you don't need vector files
|
||||||
|
**/[._]*.sw[a-p]
|
||||||
|
**/[._]s[a-rt-v][a-z]
|
||||||
|
**/[._]ss[a-gi-z]
|
||||||
|
**/[._]sw[a-p]
|
||||||
|
|
||||||
|
# Session
|
||||||
|
**/Session.vim
|
||||||
|
**/Sessionx.vim
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
**/.netrwhist
|
||||||
|
# Auto-generated tag files
|
||||||
|
**/tags
|
||||||
|
# Persistent undo
|
||||||
|
**/[._]*.un~
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/vim,linux,macos,go
|
||||||
|
|
||||||
|
**/.direnv
|
||||||
|
fly.toml
|
||||||
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
use flake
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -93,3 +93,5 @@ tags
|
||||||
[._]*.un~
|
[._]*.un~
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/vim,linux,macos,go
|
# End of https://www.toptal.com/developers/gitignore/api/vim,linux,macos,go
|
||||||
|
|
||||||
|
.direnv
|
||||||
|
|
|
||||||
16
cmd/admin/main.go
Normal file
16
cmd/admin/main.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/AYM1607/ccclip/pkg/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
privK := crypto.NewPrivateKey()
|
||||||
|
privStr := base64.StdEncoding.EncodeToString(privK.Bytes())
|
||||||
|
pubStr := base64.StdEncoding.EncodeToString(privK.PublicKey().Bytes())
|
||||||
|
|
||||||
|
fmt.Printf("Priv: %s\nPub: %s\n", privStr, pubStr)
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
var apiclient *client.Client
|
var apiclient *client.Client
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
apiclient = client.New("https://api.ccclip.io")
|
apiclient = client.New("https://clipboard.jmug.me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(registerDeviceCommand)
|
rootCmd.AddCommand(registerDeviceCommand)
|
||||||
|
registerDeviceCommand.Flags().StringVarP(&email, "email", "e", "", "email is your login identifier, ignored if your config file has has an email")
|
||||||
}
|
}
|
||||||
|
|
||||||
var registerDeviceCommand = &cobra.Command{
|
var registerDeviceCommand = &cobra.Command{
|
||||||
|
|
@ -23,8 +24,11 @@ var registerDeviceCommand = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cc.Email == "" {
|
if cc.Email != "" {
|
||||||
return errors.New("you don't have an account configured for thist device")
|
email = cc.Email
|
||||||
|
}
|
||||||
|
if email == "" {
|
||||||
|
return errors.New("provide an email through your config file or with --email")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cc.DeviceId != "" {
|
if cc.DeviceId != "" {
|
||||||
|
|
@ -35,7 +39,7 @@ var registerDeviceCommand = &cobra.Command{
|
||||||
pbk := pvk.PublicKey()
|
pbk := pvk.PublicKey()
|
||||||
|
|
||||||
password := input.ReadPassword()
|
password := input.ReadPassword()
|
||||||
res, err := apiclient.RegisterDevice(cc.Email, password, pbk.Bytes())
|
res, err := apiclient.RegisterDevice(email, password, pbk.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -43,6 +47,9 @@ var registerDeviceCommand = &cobra.Command{
|
||||||
// Write the key files first, if those fail to write then we should not
|
// Write the key files first, if those fail to write then we should not
|
||||||
// save the device Id.
|
// save the device Id.
|
||||||
cc.DeviceId = res.DeviceID
|
cc.DeviceId = res.DeviceID
|
||||||
|
if cc.Email == "" {
|
||||||
|
cc.Email = email
|
||||||
|
}
|
||||||
err = configfile.SavePrivateKey(pvk)
|
err = configfile.SavePrivateKey(pvk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
FROM golang:1.21-alpine AS builder
|
FROM golang:1.24-alpine AS builder
|
||||||
# Ensure we have a c compiler.
|
# Ensure we have a c compiler.
|
||||||
RUN apk add --no-cache build-base ca-certificates fuse3 sqlite
|
RUN apk add --no-cache build-base ca-certificates fuse3 sqlite
|
||||||
|
|
||||||
# Install LiteFS for distribute SQLite
|
|
||||||
COPY --from=flyio/litefs:0.5 /usr/local/bin/litefs /usr/local/bin/litefs
|
|
||||||
|
|
||||||
COPY cmd/server/litefs.yml /etc/litefs.yml
|
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY go.mod .
|
COPY go.mod .
|
||||||
COPY go.sum .
|
COPY go.sum .
|
||||||
|
|
@ -14,6 +9,6 @@ RUN go mod download
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN go build -ldflags='-s -w' -tags 'linux' -trimpath -o /dist/app ./cmd/server
|
RUN go build -ldflags='-s -w' -tags 'linux' -trimpath -o /dist/app ./cmd/server
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 8080
|
||||||
|
|
||||||
ENTRYPOINT ["litefs", "mount"]
|
ENTRYPOINT ["/dist/app"]
|
||||||
|
|
|
||||||
81
flake.lock
generated
Normal file
81
flake.lock
generated
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gonixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746518791,
|
||||||
|
"narHash": "sha256-MiJ11L7w18S2G5ftcoYtcrrS0JFqBaj9d5rwJFpC5Wk=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734629298,
|
||||||
|
"narHash": "sha256-KOzg4I+sRJW6rFaBzVAXKKCi2/uhDgC8YWmImKG6cs8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "fac643b357f5f203cc1fe07f3f070b7534d61334",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "release-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"gonixpkgs": "gonixpkgs",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"systems": "systems"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
32
flake.nix
Normal file
32
flake.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
description = "A basic flake with a shell";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/release-24.11";
|
||||||
|
gonixpkgs.url = "github:NixOS/nixpkgs/1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679";
|
||||||
|
systems.url = "github:nix-systems/default";
|
||||||
|
flake-utils = {
|
||||||
|
url = "github:numtide/flake-utils";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ nixpkgs, gonixpkgs, flake-utils, ... }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (
|
||||||
|
system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
gopkgs = gonixpkgs.legacyPackages.${system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
packages = with gopkgs; [
|
||||||
|
pkgs.flyctl
|
||||||
|
go
|
||||||
|
gotools
|
||||||
|
gopls
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
30
fly.toml
30
fly.toml
|
|
@ -1,30 +1,30 @@
|
||||||
# fly.toml app configuration file generated for dark-paper-8180 on 2023-11-10T08:23:22Z
|
# fly.toml app configuration file generated for ccclip on 2025-05-10T00:45:48-07:00
|
||||||
#
|
#
|
||||||
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
||||||
#
|
#
|
||||||
|
|
||||||
app = "dark-paper-8180"
|
app = 'ccclip'
|
||||||
primary_region = "sea"
|
primary_region = 'sea'
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
dockerfile = "./cmd/server/Dockerfile"
|
dockerfile = './cmd/server/Dockerfile'
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
CCCLIP_PORT = "3000"
|
CCCLIP_DATABASE_LOCATION = '/database/ccclip.db'
|
||||||
CCCLIP_DATABASE_LOCATION = "/litefs/ccclip.db"
|
|
||||||
|
|
||||||
[mounts]
|
[[mounts]]
|
||||||
source = "litefs"
|
source = 'database'
|
||||||
destination = "/var/lib/litefs"
|
destination = '/database'
|
||||||
|
|
||||||
[http_service]
|
[http_service]
|
||||||
internal_port = 8080
|
internal_port = 8080
|
||||||
force_https = true
|
force_https = true
|
||||||
auto_stop_machines = true
|
auto_stop_machines = 'stop'
|
||||||
auto_start_machines = true
|
auto_start_machines = true
|
||||||
min_machines_running = 1
|
processes = ['app']
|
||||||
processes = ["app"]
|
|
||||||
|
|
||||||
[vm]
|
[[vm]]
|
||||||
size = "shared-cpu-1x"
|
size = 'shared-cpu-1x'
|
||||||
memory = "1gb"
|
memory = '512mb'
|
||||||
|
cpu_kind = 'shared'
|
||||||
|
cpus = 1
|
||||||
|
|
|
||||||
6
go.mod
6
go.mod
|
|
@ -1,11 +1,13 @@
|
||||||
module github.com/AYM1607/ccclip
|
module github.com/AYM1607/ccclip
|
||||||
|
|
||||||
go 1.21
|
go 1.24
|
||||||
|
|
||||||
|
toolchain go1.24.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/mattn/go-isatty v0.0.20
|
github.com/mattn/go-isatty v0.0.20
|
||||||
github.com/mattn/go-sqlite3 v1.14.18
|
github.com/mattn/go-sqlite3 v1.14.19
|
||||||
github.com/oklog/ulid/v2 v2.1.0
|
github.com/oklog/ulid/v2 v2.1.0
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.0
|
||||||
golang.org/x/crypto v0.14.0
|
golang.org/x/crypto v0.14.0
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -5,8 +5,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
|
github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI=
|
||||||
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
||||||
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type ConfigFile struct {
|
||||||
var Path string
|
var Path string
|
||||||
|
|
||||||
func EnsureAndGet() (ConfigFile, error) {
|
func EnsureAndGet() (ConfigFile, error) {
|
||||||
err := os.MkdirAll(Path, os.FileMode(int(0660)))
|
err := os.MkdirAll(Path, os.FileMode(int(0770)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ConfigFile{}, fmt.Errorf("could not create config directory: %w", err)
|
return ConfigFile{}, fmt.Errorf("could not create config directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ func EnsureAndGet() (ConfigFile, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Write(c ConfigFile) error {
|
func Write(c ConfigFile) error {
|
||||||
err := os.MkdirAll(Path, os.FileMode(int(0660)))
|
err := os.MkdirAll(Path, os.FileMode(int(0770)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -55,12 +55,12 @@ func Write(c ConfigFile) error {
|
||||||
|
|
||||||
func LoadPrivateKey() (*ecdh.PrivateKey, error) {
|
func LoadPrivateKey() (*ecdh.PrivateKey, error) {
|
||||||
fp := path.Join(Path, PrivateKeyFileName)
|
fp := path.Join(Path, PrivateKeyFileName)
|
||||||
return crypto.LoadPrivateKeyFromFile(fp)
|
return crypto.LoadPrivateKeyFromFile(fp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPublicKey() (*ecdh.PublicKey, error) {
|
func LoadPublicKey() (*ecdh.PublicKey, error) {
|
||||||
fp := path.Join(Path, PublicKeyFileName)
|
fp := path.Join(Path, PublicKeyFileName)
|
||||||
return crypto.LoadPublicKeyFromFile(fp)
|
return crypto.LoadPublicKeyFromFile(fp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SavePrivateKey(k *ecdh.PrivateKey) error {
|
func SavePrivateKey(k *ecdh.PrivateKey) error {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/ecdh"
|
"crypto/ecdh"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -110,6 +111,8 @@ func (c *Client) SetClipboard(plaintext []byte, deviceId string, pvk *ecdh.Priva
|
||||||
}
|
}
|
||||||
|
|
||||||
hres, err := http.Post(c.url+"/setClipboard", "application/json", bytes.NewReader(authReqJson))
|
hres, err := http.Post(c.url+"/setClipboard", "application/json", bytes.NewReader(authReqJson))
|
||||||
|
hresBytes, _ := io.ReadAll(hres.Body)
|
||||||
|
fmt.Println(string(hresBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -194,6 +197,8 @@ func (c *Client) getDevices(deviceId string, pvk *ecdh.PrivateKey) ([]*api.Devic
|
||||||
|
|
||||||
hresBody, err := io.ReadAll(hres.Body)
|
hresBody, err := io.ReadAll(hres.Body)
|
||||||
defer hres.Body.Close()
|
defer hres.Body.Close()
|
||||||
|
hresBytes, _ := io.ReadAll(hres.Body)
|
||||||
|
fmt.Println(string(hresBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/AYM1607/ccclip/pkg/crypto"
|
"github.com/AYM1607/ccclip/pkg/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const serverPublicKeyB64 = "JTyaIVDHe1Nwqmd4NFlkvqj+MZOVp5s3JZP+T3QuoT8="
|
const serverPublicKeyB64 = "Dg6HYJ8aoQOOzGqOCw4J7tnT+QHkokjfdeWM8ktwnks="
|
||||||
|
|
||||||
var serverPublicKey *ecdh.PublicKey
|
var serverPublicKey *ecdh.PublicKey
|
||||||
|
|
||||||
|
|
|
||||||
9
internal/server/logging.go
Normal file
9
internal/server/logging.go
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
var logger *log.Logger
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
logger = log.Default()
|
||||||
|
}
|
||||||
|
|
@ -166,9 +166,11 @@ type GetUserDevicesResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) handleGetUserDevices(w http.ResponseWriter, r *http.Request) {
|
func (c *controller) handleGetUserDevices(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger.Println("handling get user devices")
|
||||||
var authReq AuthenticatedPayload
|
var authReq AuthenticatedPayload
|
||||||
err := json.NewDecoder(r.Body).Decode(&authReq)
|
err := json.NewDecoder(r.Body).Decode(&authReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Printf("decoding request: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -177,18 +179,21 @@ func (c *controller) handleGetUserDevices(w http.ResponseWriter, r *http.Request
|
||||||
// TODO: verify the request fingerprint. Right now we're just trusting that
|
// TODO: verify the request fingerprint. Right now we're just trusting that
|
||||||
// if it decrypts successfully then we can trust it.
|
// if it decrypts successfully then we can trust it.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Printf("decrypting payload: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := c.store.GetDeviceUser(authReq.DeviceID)
|
user, err := c.store.GetDeviceUser(authReq.DeviceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Printf("getting user for device: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
devices, err := c.store.GetUserDevices(user.ID)
|
devices, err := c.store.GetUserDevices(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Printf("getting devices for user: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -197,6 +202,7 @@ func (c *controller) handleGetUserDevices(w http.ResponseWriter, r *http.Request
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
err = json.NewEncoder(w).Encode(res)
|
err = json.NewEncoder(w).Encode(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Printf("encoding response: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -208,9 +214,11 @@ type SetClipboardRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) handleSetClipboard(w http.ResponseWriter, r *http.Request) {
|
func (c *controller) handleSetClipboard(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Default().Println("handling set clipboard")
|
||||||
var authReq AuthenticatedPayload
|
var authReq AuthenticatedPayload
|
||||||
err := json.NewDecoder(r.Body).Decode(&authReq)
|
err := json.NewDecoder(r.Body).Decode(&authReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Default().Printf("decoding request: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -219,18 +227,21 @@ func (c *controller) handleSetClipboard(w http.ResponseWriter, r *http.Request)
|
||||||
// TODO: verify the request fingerprint. Right now we're just trusting that
|
// TODO: verify the request fingerprint. Right now we're just trusting that
|
||||||
// if it decrypts successfully then we can trust it.
|
// if it decrypts successfully then we can trust it.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Default().Printf("decrypting authenticated payload: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := c.store.GetDeviceUser(authReq.DeviceID)
|
user, err := c.store.GetDeviceUser(authReq.DeviceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Default().Printf("getting user device: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.store.PutClipboard(user.ID, req.Clipboard)
|
err = c.store.PutClipboard(user.ID, req.Clipboard)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Default().Printf("putting keyboard: %s\n", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue