This is a password manager written in Go. Graduation project of Advanced golang course at Yandex.Praktikum
git clone https://github.com/gynshu-one/goph-keeper
cd goph-keeper
To build and run the server inside the project directory:
make serve
This command does the following:"
@echo "Starting server..."
# generates self-signed certificate
mkdir -p ~/.goph-keeper
openssl req -x509 -newkey rsa:4096 -keyout ~/.goph-keeper/key.pem -out ~/.goph-keeper/cert.pem -days 365 -nodes -subj '/CN=localhost' -addext 'subjectAltName = DNS:localhost'
# runs mongodb
docker-compose up --build -d
# builds the server
go build -o ./server_cmd ./server/cmd/main.go
# runs the server with the pre-generated certificate and predefined mongo URI
./server_cmd -port 8080 -cert ~/.goph-keeper/cert.pem -key ~/.goph-keeper/key.pem -mongo_uri mongodb://admin:password@localhost:27017
port
is the server port default: 8080
cert
is the path to the certificate default: cert/cert.pem
key
is the path to the key default: cert/key.pem
mongo_uri
is the mongodb uri default: mongodb://admin:password@localhost:27017
If you run the server without any flags, or without specifying a certificate and key, it will generate a self-signed certificate for localhost
and run on port 8080.
To build and run the client inside the project directory:
make ui
This command does the following:"
@echo "Building client..."
go build -o ./client_cmd ./client/cmd/main.go
./client_cmd -addr localhost:8080 -poll 5s -dump 10s
addr
is the server ip address default: localhost:8080
poll
is the timer for synchronizing data with server default: 5s
dump
is the timer for dumping data to the server default: 10s
You can also run client without any flags and it will use default values
see Makefile
go install golang.org/x/tools/cmd/godoc
godoc -http=:6060
then visit:
http://localhost:6060/pkg/github.com/gynshu-one/goph-keeper/
For simplicity, the password and secret are stored in the OS keychain. Every other log in would grab first user from OS keychain for password and secret
After logging in to a server with only password (Not secret) you will receive session cookie for 24 hours.
The client will read the config.json file from its working directory.
{
"SERVER_IP": "localhost:8080"
}
The Server will read config.json from its working dir
{
"MONGO_URI": "mongodb://admin:password@mongo_db:27017",
"HTTP_SERVER_PORT": "8080",
"CERT_FILE_PATH": "common/cert/cert.pem",
"KEY_FILE_PATH": "common/cert/key.pem"
}
This page is basically a list of items, each item takes two rows first is a name of an item second is a type of it.
If item was deleted recently client would see name and "deleted" message.
Header part contains item creation buttons
If you click on item name you will be switched to item edition page, it looks just like creation page, except additional buttons "delete" or item's type
specific "generate one time" for login
type
Server has 4 endpoints Which are defined in router.go
Creates new user with username and password from url params
https://localhost:8080/user/create?email=your_username&password=your_password
Logs in user creates session cookie for 24 hours
https://localhost:8080/user/login?email=your_username&password=your_password
Logs out user and deletes session cookie
https://localhost:8080/user/logout
Synchronizes user data with server. Server checks if user has session cookie via middleware.go which uses session.go
https://localhost:8080/user/sync
endpoint expects POST
request with slice of DataWrapper
structs in json body
type DataWrapper struct {
// ID is the unique identifier of the data
ID string `json:"id" bson:"_id"`
// OwnerID is the user who owns this data
OwnerID string `json:"owner_id" bson:"owner_id"`
// Type is the type of the data such as ArbitraryTextType, BankCardType, BinaryType, LoginType
Type string `json:"type" bson:"type"`
Name string `json:"name" bson:"name"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at"`
CreatedAt int64 `json:"created_at" bson:"created_at"`
DeletedAt int64 `json:"deleted_at" bson:"deleted_at"`
// This is the actual data that is stored in the database
// Encrypted with user's secret
Data []byte `json:"data" bson:"data"`
}
struct in general.go
Sync
happens imminently after logging in and every item creation, deletion or update.
Client
does not have cache of the data, it only stores username in ~/.goph-keeper/user.txt file.
Deleted items would force server to remove DataWrapper
's Data field and set DeletedAt
field.