diff --git a/.drone.yml b/.drone.yml index e3b1bca95..77ef9e642 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1317,53 +1317,6 @@ steps: # - mc cp ./dist/*.dmg scw-fr-par/vikunja-releases/desktop/$VERSION/ # - mc cp ./dist/*.dmg.blockmap scw-fr-par/vikunja-releases/desktop/$VERSION/ ---- -kind: pipeline -type: docker -name: deploy-docs - -workspace: - base: /go - path: src/code.vikunja.io/api - -clone: - depth: 50 - -trigger: - event: - - push - branch: - - main - -steps: - - name: theme - image: kolaente/toolbox - pull: always - commands: - - mkdir docs/themes/vikunja -p - - cd docs/themes/vikunja - - wget https://dl.vikunja.io/theme/vikunja-theme.tar.gz - - tar -xzf vikunja-theme.tar.gz - - - name: build - image: klakegg/hugo:0.111.3 - pull: always - commands: - - cd docs - - hugo - - mv public/docs/* public # Hugo seems to be not capable of setting a different theme for a home page, so we do this ugly hack to fix it. - - - name: docker - image: plugins/docker - pull: always - settings: - username: - from_secret: docker_username - password: - from_secret: docker_password - repo: vikunja/docs - context: docs/ - dockerfile: docs/Dockerfile --- kind: pipeline type: docker @@ -1380,7 +1333,6 @@ trigger: depends_on: - build-and-test - release - - deploy-docs - docker-release - desktop-release @@ -1400,6 +1352,6 @@ steps: - failure --- kind: signature -hmac: 74414af8fe9d632c1620090f562b3acd32863b38da230fb1854b8bed45055feb +hmac: 3cc4b45fcbbab5ccee14e5532b2d35f5db54cde29a8f6e854b563462e3bbb509 ... diff --git a/docs/.hugo_build.lock b/docs/.hugo_build.lock deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/Dockerfile b/docs/Dockerfile deleted file mode 100644 index a91a21896..000000000 --- a/docs/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM nginx -ADD public /usr/share/nginx/html/docs -ADD nginx.conf /etc/nginx/conf.d/default.conf \ No newline at end of file diff --git a/docs/config.yml b/docs/config.yml deleted file mode 100644 index a71a148c3..000000000 --- a/docs/config.yml +++ /dev/null @@ -1,63 +0,0 @@ -baseurl: https://vikunja.io/docs/ -title: Vikunja -theme: vikunja -enableRobotsTXT: true -canonifyURLs: false - -pygmentsUseClasses: true - -permalinks: - post: /:year/:month/:title/ - doc: /:slug/ - page: /:slug/ - default: /:slug/ - -params: - description: The to-do app to organize your life - author: The Vikunja Authors - website: https://vikunja.io - plausibleEnabled: true - plausibleDomain: vikunja.io - plausibleURL: https://analytics.kolaente.de - -markup: - goldmark: - renderer: - unsafe: true - -menu: - page: - - name: Home - url: https://vikunja.io/ - weight: 10 - - name: Features - url: https://vikunja.io/features - weight: 20 - - name: Download - url: https://vikunja.io/download - weight: 30 - - name: Blog - url: https://vikunja.io/blog/ - weight: 35 - - name: Docs - url: https://vikunja.io/docs - weight: 40 - - name: Code - url: https://code.vikunja.io/ - weight: 50 - - name: Community - url: https://community.vikunja.io/ - weight: 60 - - name: Stickers - url: https://vikunja.cloud/stickers?utm_source=io&utm_medium=io&utm_campaign=menu - weight: 65 - - name: Get it Hosted - url: https://vikunja.cloud/?utm_source=io&utm_medium=io&utm_campaign=menu - weight: 70 - sidebar: - - name: setup - weight: 10 - - name: usage - weight: 20 - - name: development - weight: 30 \ No newline at end of file diff --git a/docs/content/doc/_index.md b/docs/content/doc/_index.md deleted file mode 100644 index 7b569f43d..000000000 --- a/docs/content/doc/_index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Docs" -draft: false -url: "/docs" -type: "doc" -weight: 10 ---- -# Documentation - -This is the documentation for Vikunja. -You can find available articles in the menu on the left. - -## About - -To learn more about the what, why and how, take a look at [the features page](https://vikunja.io/en/features). - -## Start - -A good starting point if you want to install and host Vikunja on your server are [the install documentation]({{< ref "./setup/install.md">}}) -and [available configuration options]({{< ref "./setup/config.md">}}). - -## Developing - -If you want to start contributing to Vikunja, take a look at [the development docs]({{< ref "./development/development.md">}}). diff --git a/docs/content/doc/development/cli.md b/docs/content/doc/development/cli.md deleted file mode 100644 index a105ee03e..000000000 --- a/docs/content/doc/development/cli.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -date: "2019-03-31:00:00+01:00" -title: "Cli Commands" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Adding new cli commands - -All cli-related functions are located in `pkg/cmd`. -Each cli command usually calls a function in another package. -For example, the `vikunja migrate` command calls `migration.Migrate()`. - -Vikunja uses the amazing [cobra](https://github.com/spf13/cobra) library for its cli. -Please refer to its documentation for information about how to use flags etc. - -To add a new cli command, add something like the following: - -```go -func init() { - rootCmd.AddCommand(myCmd) -} - -var myCmd = &cobra.Command{ - Use: "My-command", - Short: "A short description about your command.", - Run: func(cmd *cobra.Command, args []string) { - // Call other functions - }, -} -``` diff --git a/docs/content/doc/development/config.md b/docs/content/doc/development/config.md deleted file mode 100644 index f3febc9cc..000000000 --- a/docs/content/doc/development/config.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Configuration Options" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Configuration options - -All configuration variables are declared in the `config` package. -It uses [viper](https://github.com/spf13/viper) under the hood to handle setting defaults and parsing config files. -Viper handles parsing all different configuration sources. - -## Adding new config options - -To make handling configuration parameters a bit easier, we introduced a `Key` string type in the `config` package which -you can call directly to get a config value. - -To add a new config option, you should add a new key const to `pkg/config/config.go` and possibly a default value. -Default values should always enable the feature to work or turn it off completely if it always needs -additional configuration. - -Make sure to also add the new config option to the default config file (`config.yml.sample` at the root of the repository) -with an explanatory comment to make sure it is well documented. -Then run `mage generate-docs` to generate the configuration docs from the sample file. - -## Getting Configuration Values - -To retrieve a configured value call the key with a getter for the type you need. -For example: - -```go -if config.CacheEnabled.GetBool() { - // Do something with enabled caches -} -``` - -Take a look at the methods declared on the type to see what's available. diff --git a/docs/content/doc/development/cron.md b/docs/content/doc/development/cron.md deleted file mode 100644 index 9027894da..000000000 --- a/docs/content/doc/development/cron.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "Cron Tasks" -date: 2021-07-13T23:21:52+02:00 -draft: false -menu: - sidebar: - parent: "development" ---- - -# How to add a cron job task - -Cron jobs are tasks which run on a predefined schedule. -Vikunja uses these through a light wrapper package around the excellent [github.com/robfig/cron](https://github.com/robfig/cron) package. - -The package exposes a `cron.Schedule` method with two arguments: The first one to define the schedule when the cron task should run, and the second one with the actual function to run at the schedule. You would then create a new function to register your the actual cron task in your package. - -A basic function to register a cron task looks like this: - -```go -func RegisterSomeCronTask() { - err := cron.Schedule("0 * * * *", func() { - // Do something every hour - } -} -``` - -Call the register method in the `FullInit()` method of the `init` package to actually register it. - -## Schedule Syntax - -The cron syntax uses the same on you may know from unix systems. - -It is described in detail [here](https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format). diff --git a/docs/content/doc/development/database.md b/docs/content/doc/development/database.md deleted file mode 100644 index 4cb17e4f8..000000000 --- a/docs/content/doc/development/database.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Database" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Database - -Vikunja uses [xorm](https://xorm.io/) as an abstraction layer to handle the database connection. -Please refer to [their](https://xorm.io/docs/) documentation on how to exactly use it. - -{{< table_of_contents >}} - -## Using the database - -When using the common web handlers, you get an `xorm.Session` to do database manipulations. -In other packages, use the `db.NewSession()` method to get a new database session. - -## Adding new database tables - -To add a new table to the database, create the struct and [add a migration for it]({{< ref "db-migrations.md" >}}). - -To learn more about how to configure your struct to create "good" tables, refer to [the xorm documentation](https://xorm.io/docs/). - -In most cases you will also need to implement the `TableName() string` method on the new struct to make sure the table name matches the rest of the tables - plural. - -## Adding data to test fixtures - -Adding data for test fixtures can be done via `yaml` files in `pkg/models/fixtures`. - -The name of the yaml file should match the table name in the database. -Adding values to it is done via array definition inside it. - -**Note**: Table and column names need to be in snake_case as that's what is used internally in the database and for mapping values from the database to xorm so your structs can use it. \ No newline at end of file diff --git a/docs/content/doc/development/db-migrations.md b/docs/content/doc/development/db-migrations.md deleted file mode 100644 index adc17a1b4..000000000 --- a/docs/content/doc/development/db-migrations.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -date: "2019-03-29:00:00+02:00" -title: "Database Migrations" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Database Migrations - -Vikunja runs all database migrations automatically on each start if needed. -Additionally, they can also be run directly by using the `migrate` command. - -We use [xormigrate](https://github.com/techknowlogick/xormigrate) to handle migrations, -which is based on gormigrate. - -{{< table_of_contents >}} - -## Add a new migration - -All migrations are stored in `pkg/migrations` and files should have the same name as their id. - -Each migration should have a function to apply and roll it back, as well as a numeric id (the datetime) -and a more in-depth description of what the migration actually does. - -To easily get a new id, run the following on any unix system: - -``` -date +%Y%m%d%H%M%S -``` - -New migrations should be added via the `init()` function to the `migrations` variable. -All migrations are sorted before being executed, since `init()` does not guarantee the order. - -When you're adding a new struct, you also need to add it to the `models.GetTables()` function -to ensure it will be created on new installations. - -### Generating a new migration stub - -You can easily generate a pre-filled migration stub by running `mage dev:make-migration`. -It will ask you for a table name and generate an empty migration similar to the example shown below. - -### Example - -```go -package migration - -import ( - "github.com/go-xorm/xorm" - "src.techknowlogick.com/xormigrate" -) - -// Used for rollback -type teamMembersMigration20190328074430 struct { - Updated int64 `xorm:"updated"` -} - -func (teamMembersMigration20190328074430) TableName() string { - return "team_members" -} - -func init() { - migrations = append(migrations, &xormigrate.Migration{ - ID: "20190328074430", - Description: "Remove updated from team_members", - Migrate: func(tx *xorm.Engine) error { - return dropTableColum(tx, "team_members", "updated") - }, - Rollback: func(tx *xorm.Engine) error { - return tx.Sync2(teamMembersMigration20190328074430{}) - }, - }) -} -``` - -You should always copy the changed parts of the struct you're changing when adding migrations. diff --git a/docs/content/doc/development/development.md b/docs/content/doc/development/development.md deleted file mode 100644 index 315d18ba1..000000000 --- a/docs/content/doc/development/development.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -date: "2022-09-21:00:00+02:00" -title: "Development" -toc: true -draft: false -type: "doc" -menu: - sidebar: - parent: "development" - name: "Development" ---- - -# Development - -{{< table_of_contents >}} - -## General - -To contribute to Vikunja, fork the project and work on the main branch. -Once you feel like your changes are ready, open a PR in the respective repo [on our Gitea instance](https://kolaente.dev/vikunja). -We cannot accept PRs on mirror sites. - -A maintainer will take a look and give you feedback. Once everyone is happy, the PR gets merged and released. - -If you plan to do a bigger change, it is better to open an issue for discussion first. - -The main repo is [`vikunja/vikunja`](https://kolaente.dev/vikunja/vikunja), it contains all code for the api, frontend and desktop applications. - -## Where to file issues - -You can file issues on [the Gitea repo](https://kolaente.dev/vikunja/vikunja) or [on the GitHub mirror](https://github.com/go-vikunja/vikunja), when you don't want to create an account on the Gitea instance. - -Please note that due to a spam problem, we need to manually enable accounts on Gitea after you've registered there. -To get that started, please reach out on another channel with your username. - -Another option is [the community forum](https://community.vikunja.io), especially if you want to discuss a feature in more detail. - -## API - -You'll need at least Go 1.21 to build Vikunja's api. - -A lot of developing tasks are automated using a Magefile, so make sure to [take a look at it]({{< ref "mage.md">}}). - -Make sure to check the other doc articles for specific development tasks like [testing]({{< ref "test.md">}}), -[database migrations]({{< ref "db-migrations.md" >}}) and the [project structure]({{< ref "structure.md" >}}). - -## Frontend requirements - -The code for the frontend is located in the `frontend` sub folder of the main repo. -More instructions can be found in the repo's README. - -You need to have [pnpm](https://pnpm.io/) and Node.JS in version 20 or higher installed. - -## Pull Requests - -All Pull Requests must be made [on our Gitea instance](https://kolaente.dev/vikunja). -We cannot accept PRs on mirror sites. - -Please try to make your pull request easy to review. -For that, please read the [*Best Practices for Faster Reviews*](https://github.com/kubernetes/community/blob/261cb0fd089b64002c91e8eddceebf032462ccd6/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) guide. -It has lots of useful tips for any project you may want to contribute to. -Some of the key points: - -- Make small pull requests. - The smaller, the faster to review and the more likely it will be merged soon. -- Don't make changes unrelated to your PR. - Maybe there are typos on some comments, maybe refactoring would be welcome on a function… - but if that is not related to your PR, please make *another* PR for that. -- Split big pull requests into multiple small ones. - An incremental change will be faster to review than a huge PR. -- Allow edits by maintainers. This way, the maintainers will take care of merging the PR later on instead of you. - -### PR title and summary - -In the PR title, describe the problem you are fixing, not how you are fixing it. -Use the first comment as a summary of your PR. -In the PR summary, you can describe exactly how you are fixing this problem. -Keep this summary up-to-date as the PR evolves. - -If your PR changes the UI, you must add **after** screenshots in the PR summary. -If your PR closes an issue, you must note that in a way that both GitHub and Gitea understand, i.e. by appending a paragraph like - -```text -Fixes/Closes/Resolves #. -Fixes/Closes/Resolves #. -``` - -to your summary. -Each issue that will be closed must stand on a separate line. - -If your PR is related to a discussion in the forum, you must add a link to the forum discussion. - -### Git flow - -The `main` branch is the latest and bleeding edge branch with all changes. Unstable releases are automatically created from this branch. -New Pull-Requests should be made against the `main` branch. - -A release gets tagged from the main branch with the version name as tag name. - -Backports and point-releases should go to a `release/version` branch, based on the tag they are building on top of. - -## Conventional Commits - -We're using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) because they simplify generating release notes a lot. - -It is not required to use them when creating a PR, but appreciated. diff --git a/docs/content/doc/development/errors.md b/docs/content/doc/development/errors.md deleted file mode 100644 index 84cae8fb1..000000000 --- a/docs/content/doc/development/errors.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Custom Errors" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Custom Errors - -All custom errors are defined in `pkg/models/errors.go`. -You should add new ones in this file. - -Custom errors usually have fields for the http return code, a [Vikunja-specific error code]({{< ref "../usage/errors.md">}}) -and a human-readable error message about what went wrong. - -An error consists of multiple functions and definitions: - -```go -// This struct holds any information about this specific error. -// In this case, it contains the user ID of a nonexistent user. -// This type should always be a struct, even if it has no values in it. - -// ErrUserDoesNotExist represents a "UserDoesNotExist" kind of error. -type ErrUserDoesNotExist struct { - UserID int64 -} - -// This function is mostly used in unit tests to check if a returned error is of that type. -// Every error type should have one of these. -// The name should always start with IsErr... followed by the name of the error. - -// IsErrUserDoesNotExist checks if an error is a ErrUserDoesNotExist. -func IsErrUserDoesNotExist(err error) bool { - _, ok := err.(ErrUserDoesNotExist) - return ok -} - -// This is the definition of the actual error type. -// Your error type is _required_ to implement this in order to be able to be returned as an "error" from functions. -func (err ErrUserDoesNotExist) Error() string { - return fmt.Sprintf("User does not exist [user id: %d]", err.UserID) -} - -// This const holds the Vikunja error code used to be able to identify this error without having to -// rely on an error string. -// This needs to be unique, so you should check whether the error code exists or not. -// The general convention for error codes is as follows: -// * Every "group" errors lives in a thousend something. For example all user issues are 1000-something, all -// project errors are 3000-something and so on. -// * New error codes should be the current max error code + 1. Don't take free numbers to prevent old errors -// which are deprecated and removed from being "new ones". For example, if there are error codes 1001, 1002, 1004, -// a new error should be 1005 and not 1003. - -// ErrCodeUserDoesNotExist holds the unique world-error code of this error -const ErrCodeUserDoesNotExist = 1005 - -// This is the implementation which returns an http error which is then passed to the client. -// Here you define the http status code with which one the error will be returned, the Vikunja error code and -// a human-readable error message. - -// HTTPError holds the http error description -func (err ErrUserDoesNotExist) HTTPError() web.HTTPError { - return web.HTTPError{ - HTTPCode: http.StatusNotFound, - Code: ErrCodeUserDoesNotExist, - Message: "The user does not exist.", - } -} -``` \ No newline at end of file diff --git a/docs/content/doc/development/events-and-listeners.md b/docs/content/doc/development/events-and-listeners.md deleted file mode 100644 index c7c7b18d8..000000000 --- a/docs/content/doc/development/events-and-listeners.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -date: 2018-10-13T19:26:34+02:00 -title: "Events and Listeners" -draft: false -menu: - sidebar: - parent: "development" ---- - -# Events and Listeners - -Vikunja provides a simple observer pattern mechanism through events and listeners. -The basic principle of events is always the same: Something happens (=An event is fired) and something reacts to it (=A listener is called). - -Vikunja supports this principle through the `events` package. -It is built upon the excellent [watermill](https://watermill.io) library. - -Currently, it only supports dispatching events through Go Channels which makes it configuration-less. -More methods of dispatching events (like kafka or rabbitmq) are available in watermill and could be enabled with a PR. - -This document explains how events and listeners work in Vikunja, how to use them and how to create new ones. - -{{< table_of_contents >}} - -## Events - -### Definition - -Each event has to implement this interface: - -```go -type Event interface { - Name() string -} -``` - -An event can contain whatever data you need. - -When an event is dispatched, all of the data it contains will be marshaled into json for dispatching. -You then get the event with all its data back in the listener, see below. - -#### Naming Convention - -Event names should roughly have the entity they're dealing with on the left and the action on the right of the name, separated by `.`. -There's no limit to how "deep" or specific an event name can be. - -The name should have the most general concept it's describing at the left, getting more specific on the right of it. - -#### Location - -All events for a package should be declared in the `events.go` file of that package. - -### Creating a New Event - -The easiest way to create a new event is to generate it with mage: - -``` -mage dev:make-event -``` - -The function takes the name of the event as the first argument and the package where the event should be created as the second argument. -Events will be appended to the `pkg//events.go` file. -Both parameters are mandatory. - -The event type name is automatically camel-cased and gets the `Event` suffix if the provided name does not already have one. -The event name is derived from the type name and stripped of the `.event` suffix. - -The generated event will look something like the example below. - -### Dispatching events - -To dispatch an event, simply call the `events.Dispatch` method and pass in the event as parameter. - -### Example - -The `TaskCreatedEvent` is declared in the `pkg/models/events.go` file as follows: - -```go -// TaskCreatedEvent represents an event where a task has been created -type TaskCreatedEvent struct { - Task *Task - Doer web.Auth -} - -// Name defines the name for TaskCreatedEvent -func (t *TaskCreatedEvent) Name() string { - return "task.created" -} -``` - -It is dispatched in the `createTask` function of the `models` package: - -```go -func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err error) { - - // ... - - err = events.Dispatch(&TaskCreatedEvent{ - Task: t, - Doer: a, - }) - - // ... -} -``` - -As you can see, the current task and doer are injected into it. - -### Special Events - -#### `BootedEvent` - -Once Vikunja is fully initialized, right before the api web server is started, this event is fired. - -## Listeners - -A listener is a piece of code that gets executed asynchronously when an event is dispatched. - -A single event can have multiple listeners who are independent of each other. - -### Definition - -All listeners must implement this interface: - -```go -// Listener represents something that listens to events -type Listener interface { - Handle(msg *message.Message) error - Name() string -} -``` - -The `Handle` method is executed when the event this listener listens on is dispatched. -* As the single parameter, it gets the payload of the event, which is the event struct when it was dispatched decoded as json object and passed as a slice of bytes. -To use it you'll need to unmarshal it. Unfortunately there's no way to pass an already populated event object to the function because we would not know what type it has when parsing it. -* If the handler returns an error, the listener is retried 5 times, with an exponential back-off period in between retries. -If it still fails after the fifth retry, the event is nack'd and it's up to the event dispatcher to resend it. -You can learn more about this mechanism in the [watermill documentation](https://watermill.io/docs/middlewares/#retry). - -The `Name` method needs to return a unique listener name for this listener. -It should follow the same convention as event names, see above. - -### Creating a New Listener - -The easiest way to create a new listener for an event is with mage: - -``` -mage dev:make-listener -``` - -This will create a new listener type in the `pkg//listeners.go` file and implement the `Handle` and `Name` methods. -It will also pre-generate some boilerplate code to unmarshal the event from the payload. - -Furthermore, it will register the listener for its event in the `RegisterListeners()` method of the same file. -This function is called at startup and has to contain all events you want to listen for. - -### Listening for Events - -To listen for an event, you need to register the listener for the event it should be called for. -This usually happens in the `RegisterListeners()` method in `pkg//listeners.go` which is called at start up. - -The listener will never be executed if it hasn't been registered. - -See the example below. - -### Example - -```go -// RegisterListeners registers all event listeners -func RegisterListeners() { - events.RegisterListener((&ListCreatedEvent{}).Name(), &IncreaseListCounter{}) -} - -// IncreaseTaskCounter represents a listener -type IncreaseTaskCounter struct {} - -// Name defines the name for the IncreaseTaskCounter listener -func (s *IncreaseTaskCounter) Name() string { - return "task.counter.increase" -} - -// Handle is executed when the event IncreaseTaskCounter listens on is fired -func (s *IncreaseTaskCounter) Handle(payload message.Payload) (err error) { - return keyvalue.IncrBy(metrics.TaskCountKey, 1) -} -``` - -## Testing - -When testing, you should call the `events.Fake()` method in the `TestMain` function of the package you want to test. -This prevents any events from being fired and lets you assert an event has been dispatched like so: - -```go -events.AssertDispatched(t, &TaskCreatedEvent{}) -``` - -### Testing a listener - -You can call an event listener manually with the `events.TestListener` method like so: - -```go -ev := &TaskCommentCreatedEvent{ - Task: &task, - Doer: u, - Comment: tc, -} - -events.TestListener(t, ev, &SendTaskCommentNotification{}) -``` - -This will call the listener's `Handle` method and assert it did not return an error when calling. diff --git a/docs/content/doc/development/feature.md b/docs/content/doc/development/feature.md deleted file mode 100644 index 837c5a041..000000000 --- a/docs/content/doc/development/feature.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "New API Endpoints" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Add a new api endpoint/feature - -Most of the api endpoints/features of Vikunja are using the [common web handler](https://code.vikunja.io/web). -This is a library created by Vikunja in an effort to facilitate the creation of REST endpoints. - -This works by abstracting the handling of CRUD-Requests, including rights check. - -You can learn more about the web handler on [the project's repo](https://code.vikunja.io/web). - -### Helper for pagination - -Pagination limits can be calculated with a helper function, `getLimitFromPageIndex(pageIndex)` -(only available in the `models` package) from any page number. -It returns the `limit` (max-length) and `offset` parameters needed for SQL-Queries. - -You can feed this function directly into xorm's `Limit`-Function like so: - -```go -projects := []*Project{} -err := x.Limit(getLimitFromPageIndex(pageIndex, itemsPerPage)).Find(&projects) -``` - -// TODO: Add a full example from start to finish, like a tutorial on how to create a new endpoint? diff --git a/docs/content/doc/development/mage.md b/docs/content/doc/development/mage.md deleted file mode 100644 index 4d594803a..000000000 --- a/docs/content/doc/development/mage.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Magefile" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Mage - -Vikunja uses [Mage](https://magefile.org/) to script common development tasks and even releasing. -Mage is a pure go solution which allows for greater flexibility and things like better parallelization. - -This document explains what tasks are available and what they do. - -{{< table_of_contents >}} - -## Installation - -To use mage, you'll need to install the mage cli. -To install it, run the following command: - -``` -go install github.com/magefile/mage -``` - -## Categories - -There are multiple categories of subcommands in the magefile: - -* `build`: Contains commands to build a single binary -* `check`: Contains commands to statically check the source code -* `release`: Contains commands to release Vikunja with everything that's required -* `test`: Contains commands to run all kinds of tests -* `dev`: Contains commands to run development tasks -* `misc`: Commands which do not belong in either of the other categories - -## CI - -These tasks are automatically run in our CI every time someone pushes to main or you update a pull request: - -* `mage lint` -* `mage build:build` - -## Build - -### Build Vikunja - -``` -mage build -``` - -Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on. - -### clean - -``` -mage build:clean -``` - -Cleans all build and executable files - -## Check - -All check sub-commands exit with a status code of 1 if the check fails. - -Various code-checks are available: - -* `mage check:all`: Runs golangci and swagger documentation check -* `mage lint`: Checks if the code follows the rules as defined in the `.golangci.yml` config file. -* `mage lint:fix`: Fixes all code style issues which are easily fixable. - -## Release - -### Build Releases - -``` -mage release -``` - -Builds binaries for all platforms and zips them with a copy of the `templates/` folder. -All built zip files are stored into `dist/zips/`. Binaries are stored in `dist/binaries/`, -binaries bundled with `templates` are stored in `dist/releases/`. - -All cross-platform binaries built using this series of commands are built with the help of -[xgo](https://github.com/techknowlogick/xgo). The mage command will automatically install the -binary to be able to use it. - -`mage release:release` is a shortcut to execute `mage release:dirs release:windows release:linux release:darwin release:copy release:check release:os-package release:zip`. - -* `mage release:dirs` creates all directories needed -* `mage release:windows`/`release:linux`/`release:darwin` execute xgo to build for their respective platforms -* `mage release:copy` bundles binaries with a copy of the `LICENSE` and sample config files to then be zipped -* `mage release:check` creates sha256 checksums for each binary which will be included in the zip file -* `mage release:os-package` bundles a binary with the `sha256` checksum file, a sample `config.yml` and a copy of the license in a folder for each architecture -* `mage release:compress` compresses all build binaries with `upx` to save space -* `mage release:zip` packages a zip file for the files created by `release:os-package` - -### Build os packages - -``` -mage release:packages -``` - -Will build `.deb`, `.rpm` and `.apk` packages to `dist/os-packages`. - -### Make a debian repo - -``` -mage release:reprepro -``` - -Takes an already built debian package and creates a debian repo structure around it. - -Used to be run inside a [docker container](https://git.kolaente.de/konrad/reprepro-docker) in the CI process when releasing. - -## Test - -### unit - -``` -mage test:unit -``` - -Runs all tests except integration tests. - -### coverage - -``` -mage test:coverage -``` - -Runs all tests except integration tests and generates a `coverage.html` file to inspect the code coverage. - -### integration - -``` -mage test:integration -``` - -Runs all integration tests. - -## Dev - -### Create a new migration - -``` -mage dev:create-migration -``` - -Creates a new migration with the current date. -Will ask for the name of the struct you want to create a migration for. - -See also [migration docs]({{< ref "mage.md" >}}). - -## Misc - -### Format the code - -``` -mage fmt -``` - -Formats all source code using `go fmt`. - -### Generate swagger definitions from code comments - -``` -mage do-the-swag -``` - -Generates swagger definitions from the comment annotations in the code. diff --git a/docs/content/doc/development/metrics.md b/docs/content/doc/development/metrics.md deleted file mode 100644 index b0158b3ff..000000000 --- a/docs/content/doc/development/metrics.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Metrics" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Metrics - -Metrics work by exposing a `/metrics` endpoint which can then be accessed by prometheus. - -To keep the load on the database minimal, metrics are stored and updated in redis. -The `metrics` package provides several functions to create and update metrics. - -{{< table_of_contents >}} - -## Exposing New Metrics - -First, define a `const` with the metric key in redis. This is done in `pkg/metrics/metrics.go`. - -To expose a new metric, you need to register it in the `init` function inside of the `metrics` package like so: - -```go -// Register total user count metric -promauto.NewGaugeFunc(prometheus.GaugeOpts{ - Name: "vikunja_team_count", // The key of the metric. Must be unique. - Help: "The total number of teams on this instance", // A description about the metric itself. -}, func() float64 { - count, _ := GetCount(TeamCountKey) // TeamCountKey is the const we defined earlier. - return float64(count) -}) -``` - -Then you'll need to set the metrics initial value on every startup of Vikunja. -This is done in `pkg/routes/routes.go` to avoid cyclic imports. -If metrics are enabled, it checks if a redis connection is available and then sets the initial values. -A convenience function is available if the metric is based on a database struct. - -Because metrics are stored in redis, you are responsible to increase or decrease these based on criteria you define. -To do this, use `metrics.UpdateCount(value, key)` where `value` is the amount you want to change it (you can pass negative values to decrease it) and `key` it the redis key used to define the metric. - -## Using it - -A Prometheus config with a Grafana template is available at [our git repo](https://git.kolaente.de/vikunja/monitoring). diff --git a/docs/content/doc/development/migration.md b/docs/content/doc/development/migration.md deleted file mode 100644 index 41339b28e..000000000 --- a/docs/content/doc/development/migration.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -date: "2020-01-19:16:00+02:00" -title: "Migrations" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Writing a migrator for Vikunja - -It is possible to migrate data from other to-do services to Vikunja. -To make this easier, we have put together a few helpers which are documented on this page. - -In general, each migrator implements a migrator interface which is then called from a client. -The interface makes it possible to use helper methods which handle http and focus only on the implementation of the migrator itself. - -There are two ways of migrating data from another service: - -1. Through the auth-based flow where the user gives you access to their data at the third-party service through an oauth flow. You can then call the service's api on behalf of your user to get all the data. The Todoist, Trello and Microsoft To-Do Migrators use this pattern. -2. A file migration where the user uploads a file obtained from some third-party service. In your migrator, you need to parse the file and create the projects, tasks etc. The Vikunja File Import uses this pattern. - -To differentiate the two, there are two different interfaces you must implement. - -{{< table_of_contents >}} - -## Structure - -All migrator implementations live in their own package in `pkg/modules/migration/`. -When creating a new migrator, you should place all related code inside that module. - -## Migrator Interface - -The migrator interface is defined as follows: - -```go -// Migrator is the basic migrator interface which is shared among all migrators -type Migrator interface { - // Name holds the name of the migration. - // This is used to show the name to users and to keep track of users who already migrated. - Name() string - // Migrate is the interface used to migrate a user's tasks from another platform to Vikunja. - // The user object is the user who's tasks will be migrated. - Migrate(user *models.User) error - // AuthURL returns a url for clients to authenticate against. - // The use case for this are Oauth flows, where the server token should remain hidden and not - // known to the frontend. - AuthURL() string -} -``` - -## File Migrator Interface - -```go -// FileMigrator handles importing Vikunja data from a file. The implementation of it determines the format. -type FileMigrator interface { - // Name holds the name of the migration. - // This is used to show the name to users and to keep track of users who already migrated. - Name() string - // Migrate is the interface used to migrate a user's tasks, projects and other things from a file to Vikunja. - // The user object is the user who's tasks will be migrated. - Migrate(user *user.User, file io.ReaderAt, size int64) error -} -``` - -## Defining http routes - -Once your migrator implements the migration interface, it becomes possible to use the helper http handlers. -Their usage is very similar to the [general web handler](https://kolaente.dev/vikunja/web#user-content-defining-routes-using-the-standard-web-handler): - -The `RegisterRoutes(m)` method registers all routes with the scheme `/[MigratorName]/(auth|migrate|status)` for the -authUrl, Status and Migrate methods. - -```go -// This is an example for the Wunderlist migrator -if config.MigrationWunderlistEnable.GetBool() { - wunderlistMigrationHandler := &migrationHandler.MigrationWeb{ - MigrationStruct: func() migration.Migrator { - return &wunderlist.Migration{} - }, - } - wunderlistMigrationHandler.RegisterRoutes(m) -} -``` - -And for the file migrator: - -```go -vikunjaFileMigrationHandler := &migrationHandler.FileMigratorWeb{ - MigrationStruct: func() migration.FileMigrator { - return &vikunja_file.FileMigrator{} - }, -} -vikunjaFileMigrationHandler.RegisterRoutes(m) -``` - -You should also document the routes with [swagger annotations]({{< ref "swagger-docs.md" >}}). - -## Insertion helper method - -There is a method available in the `migration` package which takes a fully nested Vikunja structure and creates it with all relations. -This means you start by adding a project, then add projects inside that project, then tasks in the lists and so on. -In general, it is recommended to have one root project with all projects of the other service as child projects. - -The root structure must be present as `[]*models.ProjectWithTasksAndBuckets`. It allows to represent all of Vikunja's hierarchy as a single data structure. - -Then call the method like so: - -```go -fullVikunjaHierarchy, err := convertWunderlistToVikunja(wContent) -if err != nil { - return -} - -err = migration.InsertFromStructure(fullVikunjaHierarchy, user) -``` - -## Configuration - -If your migrator is an oauth-based one, you should add at least an option to enable or disable it. -Chances are, you'll need some more options for things like client ID and secret (if the other service uses oAuth as an authentication flow). - -The easiest way to implement an on/off switch is to check whether your migration service is enabled or not when registering the routes, and then simply don't registering the routes in case it is disabled. - -File based migrators can always be enabled. - -### Making the migrator public in `/info` - -You should make your migrator available in the `/info` endpoint so that frontends can display options to enable them or not. -To do this, add an entry to the `AvailableMigrators` field in `pkg/routes/api/v1/info.go`. diff --git a/docs/content/doc/development/notifications.md b/docs/content/doc/development/notifications.md deleted file mode 100644 index cd783ded2..000000000 --- a/docs/content/doc/development/notifications.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -date: 2021-02-07T19:26:34+02:00 -title: "Notifications" -toc: true -draft: false -menu: - sidebar: - parent: "development" ---- - -# Notifications - -Vikunja provides a simple abstraction to send notifications per mail and in the database. - -{{< table_of_contents >}} - -## Definition - -Each notification has to implement this interface: - -```go -type Notification interface { - ToMail() *Mail - ToDB() interface{} - Name() string -} -``` - -Both functions return the formatted messages for mail and database. - -A notification will only be sent or recorded for those of the two methods which don't return `nil`. -For example, if your notification should not be recorded in the database but only sent out per mail, it is enough to let the `ToDB` function return `nil`. - -### Mail notifications - -A list of chainable functions is available to compose a mail: - -```go -mail := NewMail(). - // The optional sender of the mail message. - From("test@example.com"). - // The optional recipient of the mail message. Uses the mail address of the notifiable if omitted. - To("test@otherdomain.com"). - // The subject of the mail to send. - Subject("Testmail"). - // The greeting, or "intro" line of the mail. - Greeting("Hi there,"). - // A line of text - Line("This is a line of text"). - // An action can contain a title and a url. It gets rendered as a big button in the mail. - // Note that you can have only one action per mail. - // All lines added before an action will appear in the mail before the button, all lines - // added afterwards will appear after it. - Action("The Action", "https://example.com"). - // Another line of text. - Line("This should be an outro line"). -``` - -If not provided, the `from` field of the mail contains the value configured in [`mailer.fromemail`](https://vikunja.io/docs/config-options/#fromemail). - -### Database notifications - -All data returned from the `ToDB()` method is serialized to json and saved into the database, along with the id of the notifiable, the name of the notification and a time stamp. -If you don't use the database notification, the `Name()` function can return an empty string. - -## Creating a new notification - -The easiest way to generate a mail is by using the `mage dev:make-notification` command. - -It takes the name of the notification and the package where the notification will be created. - -## Notifiables - -Notifiables can receive a notification. -A notifiable is defined with this interface: - -```go -type Notifiable interface { - // Should return the email address this notifiable has. - RouteForMail() string - // Should return the id of the notifiable entity - RouteForDB() int64 -} -``` - -The `User` type from the `user` package implements this interface. - -## Sending a notification - -Sending a notification is done with the `Notify` method from the `notifications` package. -It takes a notifiable and a notification as input. - -For example, the email confirm notification when a new user registers is sent like this: - -```go -n := &EmailConfirmNotification{ - User: update.User, - IsNew: false, -} - -err = notifications.Notify(update.User, n) -return -``` - -## Testing - -The `mail` package provides a `Fake()` method which you should call in the `MainTest` functions of your package. -If it was called, no mails are being sent and you can instead assert they have been sent with the `AssertSent` method. - -When testing, you should call the `notifications.Fake()` method in the `TestMain` function of the package you want to test. -This prevents any notifications from being sent and lets you assert a notifications has been sent like this: - -```go -notifications.AssertSent(t, &ReminderDueNotification{}) -``` - -## Example - -Take a look at the [pkg/user/notifications.go](https://code.vikunja.io/api/src/branch/main/pkg/user/notifications.go) file for a good example. diff --git a/docs/content/doc/development/releasing.md b/docs/content/doc/development/releasing.md deleted file mode 100644 index 5f59c42f4..000000000 --- a/docs/content/doc/development/releasing.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "Releasing a new Vikunja version" -date: 2022-10-28T13:06:05+02:00 -draft: false -menu: - sidebar: - parent: "development" ---- - -# Releasing a new Vikunja version - -This checklist is a collection of all steps usually involved when releasing a new version of Vikunja. -Not all steps are necessary for every release. - -* Website update - * New Features: If there are new features worth mentioning the feature page should be updated. - * New Screenshots: If an overhaul of an existing feature happened so that it now looks different from the existing screenshot, a new one is required. -* Generate changelogs (with git-cliff) -* Tag a new version: Include the changelog for that version as the tag message - * Once built: Prune the cloudflare cache so that the new versions show up at [dl.vikunja.io](https://dl.vikunja.io/) - * Update the [Flathub desktop package](https://github.com/flathub/io.vikunja.Vikunja) -* Release Highlights Blogpost - * Include a section about Vikunja in general (totally fine to copy one from the earlier blog posts) - * New Features & Improvements: Mention bigger features, potentially with screenshots. Things like refactoring are sometimes also worth mentioning. -* Publish - * Reddit - * Twitter - * Mastodon - * Chat - * Newsletter - * Forum - * If features in the release were sponsored, send an email to relevant stakeholders -* Update Vikunja Cloud version and other instances diff --git a/docs/content/doc/development/structure.md b/docs/content/doc/development/structure.md deleted file mode 100644 index 7af1696fb..000000000 --- a/docs/content/doc/development/structure.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Project Structure" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Project structure - -This document explains what each package does. - -{{< table_of_contents >}} - -## Root level - -The root directory is where [the config file]({{< ref "../setup/config.md">}}), [Magefile]({{< ref "mage.md">}}), license, drone config, -application entry point (`main.go`) and so on are located. - -## pkg - -This is where most of the magic happens. Most packages with actual code are located in this folder. - -### caldav - -This folder holds a simple caldav implementation which is responsible for the caldav feature. - -### cmd - -This package contains all cli-related files and functions. - -To learn more about how to add a new command, see [the cli docs]({{< ref "cli.md">}}). - -To learn more about how to use this cli, see [the cli usage docs]({{< ref "../usage/cli.md">}}). - -### config - -This package configures handling of Vikunja's runtime configuration. -It sets default values and sets up viper and tells it where to look for config files, how to interpret which env variables -for config etc. - -See also the [docs about adding a new configuration parameter]({{< ref "config.md" >}}). - -### cron - -See [how to add a cron task]({{< ref "cron.md" >}}). - -### db - -This package contains the db connection handling and db fixtures for testing. -Each other package gets its db connection object from this package. - -### files - -This package is responsible for all file-related things. -This means it handles saving and retrieving files from the db and the underlying file system. - -### integration - -All integration tests live here. -See [integration tests]({{< ref "test.md" >}}#integration-tests) for more details. - -### log - -Similar to `config`, this will set up the logging, based on different logging backends. -This init is called in `main.go` after the config init is done. - -### mail - -This package handles all mail sending. To learn how to send a mail, see [notifications]({{< ref "notifications.md" >}}). - -### metrics - -This package handles all metrics which are exposed to the prometheus endpoint. -To learn how it works and how to add new metrics, take a look at [how metrics work]({{< ref "metrics.md">}}). - -### migration - -This package handles all migrations. -All migrations are stored and executed in this package. - -To learn more, take a look at the [migrations docs]({{< ref "../development/db-migrations.md">}}). - -### models - -This is where most of the magic happens. -When adding new features or upgrading existing ones, that most likely happens here. - -Because this package is pretty huge, there are several documents and how-to's about it: - -* [Adding a feature]({{< ref "feature.md">}}) -* [Making calls to the database]({{< ref "database.md">}}) - -### modules - -Everything that can have multiple implementations (like a task migrator from a third-party task provider) lives in a -respective sub package in this package. - -#### auth - -Contains openid related authentication. - -#### avatar - -Contains all possible avatar providers a user can choose to set their avatar. - -#### background - -All project background providers are in sub-packages of this package. - -#### dump - -Handles everything related to the `dump` and `restore` commands of Vikunja. - -#### keyvalue - -A simple key-value store with an implementation for memory and redis. -Can be used to cache values. - -#### migration - -See [writing a migrator]({{< ref "migration.md" >}}). - -### red (redis) - -This package initializes a connection to a redis server. -This initialization is automatically done at the startup of Vikunja. - -It also has a function (`GetRedis()`) which returns a redis client object you can then use in your package -to talk to redis. - -It uses the [go-redis](https://github.com/go-redis/redis) library, please see their configuration on how to use it. - -**Note**: Only use this package directly if you have to use a direct redis connection. -In most cases, using the `keyvalue` package is a better fit. - -### routes - -This package defines all routes which are available for Vikunja clients to use. -To add a new route, see [adding a new route]({{< ref "feature.md">}}). - -#### api/v1 - -This is where all http-handler functions for the api are stored. -Every handler function which does not use the standard web handler should live here. - -### swagger - -This is where the [generated]({{< ref "mage.md#generate-swagger-definitions-from-code-comments">}}) [api docs]({{< ref "../usage/api.md">}}) live. -You usually don't need to touch this package. - -### user - -All user-related things like registration etc. live in this package. - -### utils - -A small package, containing some helper functions: - -* `MakeRandomString`: Generates a random string of a given length. -* `Sha256`: Calculates a sha256 hash from a given string. - -See their function definitions for instructions on how to use them. - -### version - -The single purpose of this package is to hold the current Vikunja version which gets overridden through build flags each time `mage release` or `mage build` is run. -It is a separate package to avoid import cycles with other packages. diff --git a/docs/content/doc/development/swagger-docs.md b/docs/content/doc/development/swagger-docs.md deleted file mode 100644 index e454696e1..000000000 --- a/docs/content/doc/development/swagger-docs.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Modifying Swagger API Docs" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Modifying swagger api docs - -The api documentation is generated using [swaggo](https://github.com/swaggo/swag) from comments. - -{{< table_of_contents >}} - -## Documenting structs - -You should always comment every field which will be exposed as a json in the api. -These comments will show up in the documentation, it'll make it easier for developers using the api. - -As an example, this is the definition of a project with all comments: - -```go -type Project struct { - // The unique, numeric id of this project. - ID int64 `xorm:"bigint autoincr not null unique pk" json:"id" param:"project"` - // The title of the project. You'll see this in the overview. - Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(1|250)" minLength:"1" maxLength:"250"` - // The description of the project. - Description string `xorm:"longtext null" json:"description"` - // The unique project short identifier. Used to build task identifiers. - Identifier string `xorm:"varchar(10) null" json:"identifier" valid:"runelength(0|10)" minLength:"0" maxLength:"10"` - // The hex color of this project - HexColor string `xorm:"varchar(6) null" json:"hex_color" valid:"runelength(0|6)" maxLength:"6"` - - OwnerID int64 `xorm:"bigint INDEX not null" json:"-"` - ParentProjectID int64 `xorm:"bigint INDEX null" json:"parent_project_id"` - ParentProject *Project `xorm:"-" json:"-"` - - // The user who created this project. - Owner *user.User `xorm:"-" json:"owner" valid:"-"` - - // Whether a project is archived. - IsArchived bool `xorm:"not null default false" json:"is_archived" query:"is_archived"` - - // The id of the file this project has set as background - BackgroundFileID int64 `xorm:"null" json:"-"` - // Holds extra information about the background set since some background providers require attribution or similar. If not null, the background can be accessed at /projects/{projectID}/background - BackgroundInformation interface{} `xorm:"-" json:"background_information"` - // Contains a very small version of the project background to use as a blurry preview until the actual background is loaded. Check out https://blurha.sh/ to learn how it works. - BackgroundBlurHash string `xorm:"varchar(50) null" json:"background_blur_hash"` - - // True if a project is a favorite. Favorite projects show up in a separate parent project. This value depends on the user making the call to the api. - IsFavorite bool `xorm:"-" json:"is_favorite"` - - // The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it. - // Will only returned when retrieving one project. - Subscription *Subscription `xorm:"-" json:"subscription,omitempty"` - - // The position this project has when querying all projects. See the tasks.position property on how to use this. - Position float64 `xorm:"double null" json:"position"` - - // A timestamp when this project was created. You cannot change this value. - Created time.Time `xorm:"created not null" json:"created"` - // A timestamp when this project was last updated. You cannot change this value. - Updated time.Time `xorm:"updated not null" json:"updated"` - - web.CRUDable `xorm:"-" json:"-"` - web.Rights `xorm:"-" json:"-"` -} -``` - -## Documenting api Endpoints - -All api routes should be documented with a comment above the handler function. -When generating the api docs with mage, the swagger cli will pick these up and put them in a neat document. - -A comment looks like this: - -```go -// @Summary Login -// @Description Logs a user in. Returns a JWT-Token to authenticate further requests. -// @tags user -// @Accept json -// @Produce json -// @Param credentials body user.Login true "The login credentials" -// @Success 200 {object} auth.Token -// @Failure 400 {object} models.Message "Invalid user password model." -// @Failure 412 {object} models.Message "Invalid totp passcode." -// @Failure 403 {object} models.Message "Invalid username or password." -// @Router /login [post] -func Login(c echo.Context) error { - // Handler logic -} -``` diff --git a/docs/content/doc/development/test.md b/docs/content/doc/development/test.md deleted file mode 100644 index 58bc11dfe..000000000 --- a/docs/content/doc/development/test.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Testing" -draft: false -type: "doc" -menu: - sidebar: - parent: "development" ---- - -# Testing - -{{< table_of_contents >}} - -## API Tests - -The following parts are about the kinds of tests in the API package and how to run them. - -### Prerequisites - -To run any kind of test, you need to specify Vikunja's [root path](https://vikunja.io/docs/config-options/#rootpath). -This is required to make sure all test fixtures are correctly loaded. - -The easies way to do that is to set the environment variable `VIKUNJA_SERVICE_ROOTPATH` to the path where you cloned the working directory. - -### Unit tests - -To run unit tests with [mage]({{< ref "mage.md">}}), execute - -``` -mage test:unit -``` - -In Vikunja, everything that is not an integration test counts as unit test - even if it accesses the db. -This definition is a bit blurry, but we haven't found a better one yet. - -### Integration tests - -All integration tests live in `pkg/integrations`. -You can run them by executing `mage test:integration`. - -The integration tests use the same config and fixtures as the unit tests and therefore have the same options available, -see at the beginning of this document. - -To run integration tests, use `mage test:integration`. - -### Running tests with config - -You can run tests with all available config variables if you want, enabling you to run tests for a lot of scenarios. -We use this in CI to run all tests with different databases. - -To use the normal config set the environment variable `VIKUNJA_TESTS_USE_CONFIG=1`. - -### Showing sql queries - -When the environment variable `UNIT_TESTS_VERBOSE=1` is set, all sql queries will be shown during the test run. - -### Fixtures - -All tests are run against a set of db fixtures. -These fixtures are defined in `pkg/models/fixtures` in YAML-Files which represent the database structure. - -When you add a new test case which requires new database entries to test against, update these files. - -#### Initializing db fixtures when writing tests - -All db fixtures for all tests live in the `pkg/db/fixtures/` folder as yaml files. -Each file has the same name as the table the fixtures are for. -You should put new fixtures in this folder. - -When initializing db fixtures, you are responsible for defining which tables your package needs in your test init function. -Usually, this is done as follows (this code snippet is taken from the `user` package): - -```go -err = db.InitTestFixtures("users") -if err != nil { - log.Fatal(err) -} -``` - -In your actual tests, you then load the fixtures into the in-memory db like so: - -```go -db.LoadAndAssertFixtures(t) -``` - -This will load all fixtures you defined in your test init method. -You should always use this method to load fixtures, the only exception is when your package tests require extra test -fixtures other than db fixtures (like files). - -## Frontend tests - -The frontend has end to end tests with Cypress that use a Vikunja instance and drive a browser against it. -Check out the docs [in the frontend repo](https://kolaente.dev/vikunja/vikunja/src/branch/main/frontend/cypress/README.md) about how they work and how to get them running. - -### Unit Tests - -To run the frontend unit tests, run - -``` -pnpm run test:unit -``` - -The frontend also has a watcher available that re-runs all unit tests every time you change something. -To use it, simply run - -``` -pnpm run test:unit-watch -``` diff --git a/docs/content/doc/development/translation-instructions-german.md b/docs/content/doc/development/translation-instructions-german.md deleted file mode 100644 index 739474436..000000000 --- a/docs/content/doc/development/translation-instructions-german.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: "German Translation Instructions" -date: 2021-06-23T23:47:34+02:00 -draft: false ---- - -# German Translation Instructions - -
-NOTE: This document contains translation instructions specific to the german translation of Vikunja. -For instructions applicable to all languages, check out the }}">general translation instructions. -
- -{{< table_of_contents >}} - -## Allgemein - -Anrede: Wenig förmlich: - -* “Du”-Form -* Keine “Amtsdeusch“-Umschreibungen, einfach so als ob man den Nutzer direkt persönlich ansprechen würde - -Genauer definiert: - -* “falsch” anstatt “nicht korrekt/inkorrekt” -* “Wende dich an …” anstatt “kontaktiere …” -* In derselben Zeit übersetzen (sonst wird aus dem englischen “is“ das deutsche “war”) -* Richtige Anführungszeichen verwenden. Also `„“` statt `''` oder `'` oder ` oder ´ - * `„` für beginnende Anführungszeichen, `“` für schließende Anführungszeichen - -Es gelten Artikel und Worttrennungen aus dem [Duden](https://duden.de). - -## Formulierungen - -* `Account` statt `Konto`. -* `TOTP` immer als ein Wort und Groß. -* `CalDAV` immer so. -* `löschen` oder `entfernen` je nach Kontext. Wenn etwas *gelöscht* wird, existiert das gelöschte Objekt und danach - nicht mehr und hat evtl. andere Objekte mitgelöscht (z.B. eine Aufgabe). Wird etwas *entfernt*, bezieht sich das - meistens auf die Beziehung zu einem anderen Objekt. Das entfernte Objekt existiert danach immernoch, z.B. beim - Entfernen eine:r Nutzer:in aus einem Team. -* Analog zu `löschen` oder `entfernen` gilt ähnliches für `hinzufügen` oder `erstellen`. Eine Aufgabe wird *erstellt*, - aber ein:e Nutzer:in nur zu einem Team *hinzugefügt*. -* `Anmeldename` anstatt `Benutzer:innenname` - -## Formulierungen in Modals und Buttons - -Es sollten die gleichen Formulierungen auf Buttons und Modals verwendet werden. - -Beispiel: Wenn der Button mit `löschen` beschriftet ist, sollte im Modal die Frage -lauten `Willst du das wirklich löschen?` und nicht `Willst du das wirklich entfernen?`. Gleiches gilt für -Erfolgs/Fehlermeldungen nach der Aktion. - -## Gendern - -Wo möglich, sollte eine geschlechtsneutrale Anrede verwendet werden. Falls diese sehr umständlich würden (siehe oben -„Amtsdeutsch-Umschreibungen“), soll mit *Doppelpunkt* gegendert werden. - -Beispiel: „Benutzer:in“ - -## Trennungen - -* E-Mail-Adresse (siehe Duden) - -## Wörter und Ausdrücke - -| Englisches Original | Verwendung in deutscher Übersetzung | -| ------------------- | -------------------- | -| Bucket | Spalte | -| Link Share | Linkfreigabe | -| Username | Anmeldename | - -## Weiterführende Links - -* https://docs.translatehouse.org/projects/localization-guide/en/latest/guide/translation_guidelines_german.html diff --git a/docs/content/doc/development/translations.md b/docs/content/doc/development/translations.md deleted file mode 100644 index 028ce5c2d..000000000 --- a/docs/content/doc/development/translations.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: "Translations" -date: 2021-06-23T22:52:06+02:00 -draft: false -menu: - sidebar: - parent: "development" ---- - -# Translations - -This document provides documentation about how to translate Vikunja. - -{{< table_of_contents >}} - -## Where to translate - -Translation happens at [crowdin](https://crowdin.com/project/vikunja). - -Currently, only the frontend (and by extension, the desktop app) is translatable. - -## Translation Instructions - -> These are the instructions for translating Vikunja in another language. -> For information about how to add new translation strings, see below. - -For all languages these translation guidelines should be applied when translating: - -* Use a less-formal style, as if you were talking to a friend. -* If the source string contains characters like `&` or `…`, the translated string should contain them as well. - -More specific instructions for some languages can be found below. - -### Wrong translation strings - -If you encounter a wrong original translation string while translating, please don't correct it in the translation. -Instead, translate it to reflect the original meaning in the translated string but add a comment under the source string to discuss potential changes. - -### Language-specific instructions - -* [German]({{< ref "./translation-instructions-german.md">}}) - -## How to add new translation strings - -All translation strings are stored in `src/i18n/lang/`. -New strings should be added only in the `en.json` file. -Strings in other languages will be synced through [crowdin](https://crowdin.com/project/vikunja) and should not be added directly as a PR/commit in the frontend repo. - -## Requesting a new language - -If you want to start translating Vikunja in a language not yet available in Vikunja, please request the language through the crowdin interface. -If you have issues with this or need a discussion before doing so, please [contact us](https://vikunja.io/contact/) or [start a discussion in the forum](https://community.vikunja.io). - -Once at least 50% of all translation strings are translated and approved, they will be added and distributed with the Vikunja frontend for users to select and use Vikunja with them. diff --git a/docs/content/doc/setup/backups.md b/docs/content/doc/setup/backups.md deleted file mode 100644 index 47284a5d3..000000000 --- a/docs/content/doc/setup/backups.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "What to backup" -draft: false -type: "doc" -menu: - sidebar: - parent: "setup" ---- - -# What to backup - -There are two parts you need to back up: The database and attachment files. - -{{< table_of_contents >}} - -## Files - -To back up attachments and other files, it is enough to copy them [from the attachments folder]({{< ref "config.md" >}}#basepath) to some other place. - -## Database - -### MySQL - -To create a backup from mysql use the `mysqldump` command: - -``` -mysqldump -u -p -h > vkunja-backup.sql -``` - -You will be prompted for the password of the mysql user. - -To restore it, simply pipe it back into the `mysql` command: - -``` -mysql -u -p -h < vkunja-backup.sql -``` - -### PostgreSQL - -To create a backup from PostgreSQL use the `pg_dump` command: - -``` -pg_dump -U -h > vikunja-backup.sql -``` - -You might be prompted for the password of the database user. - -To restore it, simply pipe it back into the `psql` command: - -``` -psql -U -h < vikunja-backup.sql -``` - -For more information, please visit the [relevant PostgreSQL documentation](https://www.postgresql.org/docs/12/backup-dump.html). - -### SQLite - -To back up sqllite databases, it is enough to copy the [database file]({{< ref "config.md" >}}#path) to somewhere else. diff --git a/docs/content/doc/setup/build-from-source.md b/docs/content/doc/setup/build-from-source.md deleted file mode 100644 index a471d2c7c..000000000 --- a/docs/content/doc/setup/build-from-source.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -date: "2022-09-21:00:00+02:00" -title: "Build from sources" -draft: false -type: "doc" -menu: - sidebar: - parent: "setup" ---- - -# Build Vikunja from source - -To fully build Vikunja from source files, you need to build the api and frontend. - -{{< table_of_contents >}} - -## General Preparations - -1. Make sure you have git installed -2. Clone the repo with `git clone https://code.vikunja.io/vikunja` and switch into the directory. -3. Check out the version you want to build with `git checkout VERSION` - replace `VERSION` with the version want to use. If you don't do this, you'll build the [latest unstable build]({{< ref "versions.md">}}), which might contain bugs. - -## Frontend - -The code for the frontend is located in the `frontend/` sub folder of the main repo. - -1. Make sure you have [pnpm](https://pnpm.io/installation) properly installed on your system. -2. Install all dependencies with `pnpm install` -3. Build the frontend with `pnpm run build`. This will result in a static js bundle in the `dist/` folder. -4. You can either deploy that static js bundle directly, or read on to learn how to bundle it all up in a static binary with the api. - -## API - -The Vikunja API has no other dependencies than go itself. -That means compiling it boils down to these steps: - -1. Make sure [Go](https://golang.org/doc/install) is properly installed on your system. You'll need at least Go `1.21`. -2. Make sure [Mage](https://magefile.org) is properly installed on your system. -3. If you did not build the frontend in the steps before, you need to either do that or create a dummy index file with `mkdir -p frontend/dist && touch frontend/dist/index.html`. -4. Run `mage build` in the source of the main repo. This will build a binary in the root of the repo which will be able to run on your system. - -### Build for different architectures - -To build for other platforms and architectures than the one you're currently on, simply run `mage release` or `mage release:{linux|windows|darwin}`. - -More options are available, please refer to the [magefile docs]({{< ref "../development/mage.md">}}) for more details. diff --git a/docs/content/doc/setup/config.md b/docs/content/doc/setup/config.md deleted file mode 100644 index 528f8333d..000000000 --- a/docs/content/doc/setup/config.md +++ /dev/null @@ -1,1456 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Config options" -draft: false -type: "doc" -menu: - sidebar: - parent: "setup" ---- - -# Configuration options - -You can either use a `config.yml` file in the root directory of vikunja or set almost all config option with environment variables. If you have both, the value set in the config file is used. -Right now it is not possible to configure openid authentication via environment variables. - -Variables are nested in the `config.yml`, these nested variables become `VIKUNJA_FIRST_CHILD` when configuring via -environment variables. So setting - -``` -export VIKUNJA_FIRST_CHILD=true -``` - -is the same as defining it in a `config.yml` like so: - -```yaml -first: - child: true -``` - -# Formats - -Vikunja supports using `toml`, `yaml`, `hcl`, `ini`, `json`, envfile, env variables and Java Properties files. -We recommend yaml or toml, but you're free to use whatever you want. - -Vikunja provides a default [`config.yml`](https://kolaente.dev/vikunja/vikunja/src/branch/main/config.yml.sample) file which you can use as a starting point. - -# Config file locations - -Vikunja will search on various places for a config file: - -* Next to the location of the binary -* In the `service.rootpath` location set in a config (remember you can set config arguments via environment variables) -* In `/etc/vikunja` -* In `~/.config/vikunja` - -# Default configuration with explanations - -The following explains all possible config variables and their defaults. -You can find a full example configuration file in [here](https://code.vikunja.io/api/src/branch/main/config.yml.sample). - -If you don't provide a value in your config file, their default will be used. - -## Nesting - -Most config variables are nested under some "higher-level" key. -For example, the `interface` config variable is a child of the `service` key. - -The docs below aim to reflect that leveling, but please also have a look at [the default config](https://code.vikunja.io/api/src/branch/main/config.yml.sample) file -to better grasp how the nesting looks like. - - - ---- - -## service - - - -### JWTSecret - -This token is used to verify issued JWT tokens. -Default is a random token which will be generated at each startup of vikunja. -(This means all already issued tokens will be invalid once you restart vikunja) - -Default: `` - -Full path: `service.JWTSecret` - -Environment path: `VIKUNJA_SERVICE_JWTSECRET` - - -### jwtttl - -The duration of the issued JWT tokens in seconds. -The default is 259200 seconds (3 Days). - -Default: `259200` - -Full path: `service.jwtttl` - -Environment path: `VIKUNJA_SERVICE_JWTTTL` - - -### jwtttllong - -The duration of the "remember me" time in seconds. When the login request is made with -the long param set, the token returned will be valid for this period. -The default is 2592000 seconds (30 Days). - -Default: `2592000` - -Full path: `service.jwtttllong` - -Environment path: `VIKUNJA_SERVICE_JWTTTLLONG` - - -### interface - -The interface on which to run the webserver - -Default: `:3456` - -Full path: `service.interface` - -Environment path: `VIKUNJA_SERVICE_INTERFACE` - - -### unixsocket - -Path to Unix socket. If set, it will be created and used instead of tcp - -Default: `` - -Full path: `service.unixsocket` - -Environment path: `VIKUNJA_SERVICE_UNIXSOCKET` - - -### unixsocketmode - -Permission bits for the Unix socket. Note that octal values must be prefixed by "0o", e.g. 0o660 - -Default: `` - -Full path: `service.unixsocketmode` - -Environment path: `VIKUNJA_SERVICE_UNIXSOCKETMODE` - - -### publicurl - -The public facing URL where your users can reach Vikunja. Used in emails and for the communication between api and frontend. - -Default: `` - -Full path: `service.publicurl` - -Environment path: `VIKUNJA_SERVICE_PUBLICURL` - - -### rootpath - -The base path on the file system where the binary and assets are. -Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder -with a config file which will then be used. - -Default: `` - -Full path: `service.rootpath` - -Environment path: `VIKUNJA_SERVICE_ROOTPATH` - - -### maxitemsperpage - -The max number of items which can be returned per page - -Default: `50` - -Full path: `service.maxitemsperpage` - -Environment path: `VIKUNJA_SERVICE_MAXITEMSPERPAGE` - - -### enablecaldav - -Enable the caldav endpoint, see the docs for more details - -Default: `true` - -Full path: `service.enablecaldav` - -Environment path: `VIKUNJA_SERVICE_ENABLECALDAV` - - -### motd - -Set the motd message, available from the /info endpoint - -Default: `` - -Full path: `service.motd` - -Environment path: `VIKUNJA_SERVICE_MOTD` - - -### enablelinksharing - -Enable sharing of project via a link - -Default: `true` - -Full path: `service.enablelinksharing` - -Environment path: `VIKUNJA_SERVICE_ENABLELINKSHARING` - - -### enableregistration - -Whether to let new users registering themselves or not - -Default: `true` - -Full path: `service.enableregistration` - -Environment path: `VIKUNJA_SERVICE_ENABLEREGISTRATION` - - -### enabletaskattachments - -Whether to enable task attachments or not - -Default: `true` - -Full path: `service.enabletaskattachments` - -Environment path: `VIKUNJA_SERVICE_ENABLETASKATTACHMENTS` - - -### timezone - -The time zone all timestamps are in. Please note that time zones have to use [the official tz database names](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). UTC or GMT offsets won't work. - -Default: `GMT` - -Full path: `service.timezone` - -Environment path: `VIKUNJA_SERVICE_TIMEZONE` - - -### enabletaskcomments - -Whether task comments should be enabled or not - -Default: `true` - -Full path: `service.enabletaskcomments` - -Environment path: `VIKUNJA_SERVICE_ENABLETASKCOMMENTS` - - -### enabletotp - -Whether totp is enabled. In most cases you want to leave that enabled. - -Default: `true` - -Full path: `service.enabletotp` - -Environment path: `VIKUNJA_SERVICE_ENABLETOTP` - - -### testingtoken - -If not empty, this will enable `/test/{table}` endpoints which allow to put any content in the database. -Used to reset the db before frontend tests. Because this is quite a dangerous feature allowing for lots of harm, -each request made to this endpoint needs to provide an `Authorization: ` header with the token from below.
-**You should never use this unless you know exactly what you're doing** - -Default: `` - -Full path: `service.testingtoken` - -Environment path: `VIKUNJA_SERVICE_TESTINGTOKEN` - - -### enableemailreminders - -If enabled, vikunja will send an email to everyone who is either assigned to a task or created it when a task reminder -is due. - -Default: `true` - -Full path: `service.enableemailreminders` - -Environment path: `VIKUNJA_SERVICE_ENABLEEMAILREMINDERS` - - -### enableuserdeletion - -If true, will allow users to request the complete deletion of their account. When using external authentication methods -it may be required to coordinate with them in order to delete the account. This setting will not affect the cli commands -for user deletion. - -Default: `true` - -Full path: `service.enableuserdeletion` - -Environment path: `VIKUNJA_SERVICE_ENABLEUSERDELETION` - - -### maxavatarsize - -The maximum size clients will be able to request for user avatars. -If clients request a size bigger than this, it will be changed on the fly. - -Default: `1024` - -Full path: `service.maxavatarsize` - -Environment path: `VIKUNJA_SERVICE_MAXAVATARSIZE` - - -### demomode - -If set to true, the frontend will show a big red warning not to use this instance for real data as it will be cleared out. -You probably don't need to set this value, it was created specifically for usage on [try](https://try.vikunja.io). - -Default: `false` - -Full path: `service.demomode` - -Environment path: `VIKUNJA_SERVICE_DEMOMODE` - - -### allowiconchanges - -Allow changing the logo and other icons based on various occasions throughout the year. - -Default: `true` - -Full path: `service.allowiconchanges` - -Environment path: `VIKUNJA_SERVICE_ALLOWICONCHANGES` - - -### customlogourl - -Allow using a custom logo via external URL. - -Default: `` - -Full path: `service.customlogourl` - -Environment path: `VIKUNJA_SERVICE_CUSTOMLOGOURL` - - -### enablepublicteams - -Enables the public team feature. If enabled, it is possible to configure teams to be public, which makes them -discoverable when sharing a project, therefore not only showing teams the user is member of. - -Default: `false` - -Full path: `service.enablepublicteams` - -Environment path: `VIKUNJA_SERVICE_ENABLEPUBLICTEAMS` - - ---- - -## sentry - - - -### enabled - -If set to true, enables anonymous error tracking of api errors via Sentry. This allows us to gather more -information about errors in order to debug and fix it. - -Default: `false` - -Full path: `sentry.enabled` - -Environment path: `VIKUNJA_SENTRY_ENABLED` - - -### dsn - -Configure the Sentry dsn used for api error tracking. Only used when Sentry is enabled for the api. - -Default: `https://440eedc957d545a795c17bbaf477497c@o1047380.ingest.sentry.io/4504254983634944` - -Full path: `sentry.dsn` - -Environment path: `VIKUNJA_SENTRY_DSN` - - -### frontendenabled - -If set to true, enables anonymous error tracking of frontend errors via Sentry. This allows us to gather more -information about errors in order to debug and fix it. - -Default: `false` - -Full path: `sentry.frontendenabled` - -Environment path: `VIKUNJA_SENTRY_FRONTENDENABLED` - - -### frontenddsn - -Configure the Sentry dsn used for frontend error tracking. Only used when Sentry is enabled for the frontend. - -Default: `https://85694a2d757547cbbc90cd4b55c5a18d@o1047380.ingest.sentry.io/6024480` - -Full path: `sentry.frontenddsn` - -Environment path: `VIKUNJA_SENTRY_FRONTENDDSN` - - ---- - -## database - - - -### type - -Database type to use. Supported values are mysql, postgres and sqlite. Vikunja is able to run with MySQL 8.0+, Mariadb 10.2+, PostgreSQL 12+, and sqlite. - -Default: `sqlite` - -Full path: `database.type` - -Environment path: `VIKUNJA_DATABASE_TYPE` - - -### user - -Database user which is used to connect to the database. - -Default: `vikunja` - -Full path: `database.user` - -Environment path: `VIKUNJA_DATABASE_USER` - - -### password - -Database password - -Default: `` - -Full path: `database.password` - -Environment path: `VIKUNJA_DATABASE_PASSWORD` - - -### host - -Database host - -Default: `localhost` - -Full path: `database.host` - -Environment path: `VIKUNJA_DATABASE_HOST` - - -### database - -Database to use - -Default: `vikunja` - -Full path: `database.database` - -Environment path: `VIKUNJA_DATABASE_DATABASE` - - -### path - -When using sqlite, this is the path where to store the data - -Default: `./vikunja.db` - -Full path: `database.path` - -Environment path: `VIKUNJA_DATABASE_PATH` - - -### maxopenconnections - -Sets the max open connections to the database. Only used when using mysql and postgres. - -Default: `100` - -Full path: `database.maxopenconnections` - -Environment path: `VIKUNJA_DATABASE_MAXOPENCONNECTIONS` - - -### maxidleconnections - -Sets the maximum number of idle connections to the db. - -Default: `50` - -Full path: `database.maxidleconnections` - -Environment path: `VIKUNJA_DATABASE_MAXIDLECONNECTIONS` - - -### maxconnectionlifetime - -The maximum lifetime of a single db connection in milliseconds. - -Default: `10000` - -Full path: `database.maxconnectionlifetime` - -Environment path: `VIKUNJA_DATABASE_MAXCONNECTIONLIFETIME` - - -### sslmode - -Secure connection mode. Only used with postgres. -(see https://pkg.go.dev/github.com/lib/pq?tab=doc#hdr-Connection_String_Parameters) - -Default: `disable` - -Full path: `database.sslmode` - -Environment path: `VIKUNJA_DATABASE_SSLMODE` - - -### sslcert - -The path to the client cert. Only used with postgres. - -Default: `` - -Full path: `database.sslcert` - -Environment path: `VIKUNJA_DATABASE_SSLCERT` - - -### sslkey - -The path to the client key. Only used with postgres. - -Default: `` - -Full path: `database.sslkey` - -Environment path: `VIKUNJA_DATABASE_SSLKEY` - - -### sslrootcert - -The path to the ca cert. Only used with postgres. - -Default: `` - -Full path: `database.sslrootcert` - -Environment path: `VIKUNJA_DATABASE_SSLROOTCERT` - - -### tls - -Enable SSL/TLS for mysql connections. Options: false, true, skip-verify, preferred - -Default: `false` - -Full path: `database.tls` - -Environment path: `VIKUNJA_DATABASE_TLS` - - ---- - -## typesense - - - -### enabled - -Whether to enable the Typesense integration. If true, all tasks will be synced to the configured Typesense -instance and all search and filtering will run through Typesense instead of only through the database. -Typesense allows fast fulltext search including fuzzy matching support. It may return different results than -what you'd get with a database-only search. - -Default: `false` - -Full path: `typesense.enabled` - -Environment path: `VIKUNJA_TYPESENSE_ENABLED` - - -### url - -The url to the Typesense instance you want to use. Can be hosted locally or in Typesense Cloud as long -as Vikunja is able to reach it. - -Default: `` - -Full path: `typesense.url` - -Environment path: `VIKUNJA_TYPESENSE_URL` - - -### apikey - -The Typesense API key you want to use. - -Default: `` - -Full path: `typesense.apikey` - -Environment path: `VIKUNJA_TYPESENSE_APIKEY` - - ---- - -## redis - - - -### enabled - -Whether to enable redis or not - -Default: `false` - -Full path: `redis.enabled` - -Environment path: `VIKUNJA_REDIS_ENABLED` - - -### host - -The host of the redis server including its port. - -Default: `localhost:6379` - -Full path: `redis.host` - -Environment path: `VIKUNJA_REDIS_HOST` - - -### password - -The password used to authenticate against the redis server - -Default: `` - -Full path: `redis.password` - -Environment path: `VIKUNJA_REDIS_PASSWORD` - - -### db - -0 means default database - -Default: `0` - -Full path: `redis.db` - -Environment path: `VIKUNJA_REDIS_DB` - - ---- - -## cors - - - -### enable - -Whether to enable or disable cors headers. -Note: If you want to put the frontend and the api on separate domains or ports, you will need to enable this. - Otherwise the frontend won't be able to make requests to the api through the browser. - -Default: `false` - -Full path: `cors.enable` - -Environment path: `VIKUNJA_CORS_ENABLE` - - -### origins - -A list of origins which may access the api. These need to include the protocol (`http://` or `https://`) and port, if any. - -Default: `` - -Full path: `cors.origins` - -Environment path: `VIKUNJA_CORS_ORIGINS` - - -### maxage - -How long (in seconds) the results of a preflight request can be cached. - -Default: `0` - -Full path: `cors.maxage` - -Environment path: `VIKUNJA_CORS_MAXAGE` - - ---- - -## mailer - - - -### enabled - -Whether to enable the mailer or not. If it is disabled, all users are enabled right away and password reset is not possible. - -Default: `false` - -Full path: `mailer.enabled` - -Environment path: `VIKUNJA_MAILER_ENABLED` - - -### host - -SMTP Host - -Default: `` - -Full path: `mailer.host` - -Environment path: `VIKUNJA_MAILER_HOST` - - -### port - -SMTP Host port. -**NOTE:** If you're unable to send mail and the only error you see in the logs is an `EOF`, try setting the port to `25`. - -Default: `587` - -Full path: `mailer.port` - -Environment path: `VIKUNJA_MAILER_PORT` - - -### authtype - -SMTP Auth Type. Can be either `plain`, `login` or `cram-md5`. - -Default: `plain` - -Full path: `mailer.authtype` - -Environment path: `VIKUNJA_MAILER_AUTHTYPE` - - -### username - -SMTP username - -Default: `user` - -Full path: `mailer.username` - -Environment path: `VIKUNJA_MAILER_USERNAME` - - -### password - -SMTP password - -Default: `` - -Full path: `mailer.password` - -Environment path: `VIKUNJA_MAILER_PASSWORD` - - -### skiptlsverify - -Whether to skip verification of the tls certificate on the server - -Default: `false` - -Full path: `mailer.skiptlsverify` - -Environment path: `VIKUNJA_MAILER_SKIPTLSVERIFY` - - -### fromemail - -The default from address when sending emails - -Default: `mail@vikunja` - -Full path: `mailer.fromemail` - -Environment path: `VIKUNJA_MAILER_FROMEMAIL` - - -### queuelength - -The length of the mail queue. - -Default: `100` - -Full path: `mailer.queuelength` - -Environment path: `VIKUNJA_MAILER_QUEUELENGTH` - - -### queuetimeout - -The timeout in seconds after which the current open connection to the mailserver will be closed. - -Default: `30` - -Full path: `mailer.queuetimeout` - -Environment path: `VIKUNJA_MAILER_QUEUETIMEOUT` - - -### forcessl - -By default, vikunja will try to connect with starttls, use this option to force it to use ssl. - -Default: `false` - -Full path: `mailer.forcessl` - -Environment path: `VIKUNJA_MAILER_FORCESSL` - - ---- - -## log - - - -### path - -A folder where all the logfiles should go. - -Default: `logs` - -Full path: `log.path` - -Environment path: `VIKUNJA_LOG_PATH` - - -### enabled - -Whether to show any logging at all or none - -Default: `true` - -Full path: `log.enabled` - -Environment path: `VIKUNJA_LOG_ENABLED` - - -### standard - -Where the normal log should go. Possible values are stdout, stderr, file or off to disable standard logging. - -Default: `stdout` - -Full path: `log.standard` - -Environment path: `VIKUNJA_LOG_STANDARD` - - -### level - -Change the log level. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. - -Default: `INFO` - -Full path: `log.level` - -Environment path: `VIKUNJA_LOG_LEVEL` - - -### database - -Whether or not to log database queries. Useful for debugging. Possible values are stdout, stderr, file or off to disable database logging. - -Default: `off` - -Full path: `log.database` - -Environment path: `VIKUNJA_LOG_DATABASE` - - -### databaselevel - -The log level for database log messages. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. - -Default: `WARNING` - -Full path: `log.databaselevel` - -Environment path: `VIKUNJA_LOG_DATABASELEVEL` - - -### http - -Whether to log http requests or not. Possible values are stdout, stderr, file or off to disable http logging. - -Default: `stdout` - -Full path: `log.http` - -Environment path: `VIKUNJA_LOG_HTTP` - - -### echo - -Echo has its own logging which usually is unnecessary, which is why it is disabled by default. Possible values are stdout, stderr, file or off to disable standard logging. - -Default: `off` - -Full path: `log.echo` - -Environment path: `VIKUNJA_LOG_ECHO` - - -### events - -Whether or not to log events. Useful for debugging. Possible values are stdout, stderr, file or off to disable events logging. - -Default: `off` - -Full path: `log.events` - -Environment path: `VIKUNJA_LOG_EVENTS` - - -### eventslevel - -The log level for event log messages. Possible values (case-insensitive) are ERROR, INFO, DEBUG. - -Default: `info` - -Full path: `log.eventslevel` - -Environment path: `VIKUNJA_LOG_EVENTSLEVEL` - - -### mail - -Whether or not to log mail log messages. This will not log mail contents. Possible values are stdout, stderr, file or off to disable mail-related logging. - -Default: `off` - -Full path: `log.mail` - -Environment path: `VIKUNJA_LOG_MAIL` - - -### maillevel - -The log level for mail log messages. Possible values (case-insensitive) are ERROR, WARNING, INFO, DEBUG. - -Default: `info` - -Full path: `log.maillevel` - -Environment path: `VIKUNJA_LOG_MAILLEVEL` - - ---- - -## ratelimit - - - -### enabled - -whether or not to enable the rate limit - -Default: `false` - -Full path: `ratelimit.enabled` - -Environment path: `VIKUNJA_RATELIMIT_ENABLED` - - -### kind - -The kind on which rates are based. Can be either "user" for a rate limit per user or "ip" for an ip-based rate limit. - -Default: `user` - -Full path: `ratelimit.kind` - -Environment path: `VIKUNJA_RATELIMIT_KIND` - - -### period - -The time period in seconds for the limit - -Default: `60` - -Full path: `ratelimit.period` - -Environment path: `VIKUNJA_RATELIMIT_PERIOD` - - -### limit - -The max number of requests a user is allowed to do in the configured time period - -Default: `100` - -Full path: `ratelimit.limit` - -Environment path: `VIKUNJA_RATELIMIT_LIMIT` - - -### store - -The store where the limit counter for each user is stored. -Possible values are "keyvalue", "memory" or "redis". -When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. - -Default: `keyvalue` - -Full path: `ratelimit.store` - -Environment path: `VIKUNJA_RATELIMIT_STORE` - - -### noauthlimit - -The number of requests a user can make from the same IP to all unauthenticated routes (login, register, -password confirmation, email verification, password reset request) per minute. This limit cannot be disabled. -You should only change this if you know what you're doing. - -Default: `10` - -Full path: `ratelimit.noauthlimit` - -Environment path: `VIKUNJA_RATELIMIT_NOAUTHLIMIT` - - ---- - -## files - - - -### basepath - -The path where files are stored - -Default: `./files` - -Full path: `files.basepath` - -Environment path: `VIKUNJA_FILES_BASEPATH` - - -### maxsize - -The maximum size of a file, as a human-readable string. -Warning: The max size is limited 2^64-1 bytes due to the underlying datatype - -Default: `20MB` - -Full path: `files.maxsize` - -Environment path: `VIKUNJA_FILES_MAXSIZE` - - ---- - -## migration - - - -### todoist - -Default: `` - -Full path: `migration.todoist` - -Environment path: `VIKUNJA_MIGRATION_TODOIST` - - -### trello - -Default: `` - -Full path: `migration.trello` - -Environment path: `VIKUNJA_MIGRATION_TRELLO` - - -### microsofttodo - -Default: `` - -Full path: `migration.microsofttodo` - -Environment path: `VIKUNJA_MIGRATION_MICROSOFTTODO` - - ---- - -## avatar - - - -### gravatarexpiration - -When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires - -Default: `3600` - -Full path: `avatar.gravatarexpiration` - -Environment path: `VIKUNJA_AVATAR_GRAVATAREXPIRATION` - - ---- - -## backgrounds - - - -### enabled - -Whether to enable backgrounds for projects at all. - -Default: `true` - -Full path: `backgrounds.enabled` - -Environment path: `VIKUNJA_BACKGROUNDS_ENABLED` - - -### providers - -Default: `` - -Full path: `backgrounds.providers` - -Environment path: `VIKUNJA_BACKGROUNDS_PROVIDERS` - - ---- - -## legal - -Legal urls -Will be shown in the frontend if configured here - - - -### imprinturl - -Default: `` - -Full path: `legal.imprinturl` - -Environment path: `VIKUNJA_LEGAL_IMPRINTURL` - - -### privacyurl - -Default: `` - -Full path: `legal.privacyurl` - -Environment path: `VIKUNJA_LEGAL_PRIVACYURL` - - ---- - -## keyvalue - -Key Value Storage settings -The Key Value Storage is used for different kinds of things like metrics and a few cache systems. - - - -### type - -The type of the storage backend. Can be either "memory" or "redis". If "redis" is chosen it needs to be configured separately. - -Default: `memory` - -Full path: `keyvalue.type` - -Environment path: `VIKUNJA_KEYVALUE_TYPE` - - ---- - -## auth - - - -### local - -Local authentication will let users log in and register (if enabled) through the db. -This is the default auth mechanism and does not require any additional configuration. - -Default: `` - -Full path: `auth.local` - -Environment path: `VIKUNJA_AUTH_LOCAL` - - -### openid - -OpenID configuration will allow users to authenticate through a third-party OpenID Connect compatible provider.
-The provider needs to support the `openid`, `profile` and `email` scopes.
-**Note:** Some openid providers (like Gitlab) only make the email of the user available through OpenID if they have set it to be publicly visible. -If the email is not public in those cases, authenticating will fail. -+**Note 2:** The frontend expects the third party to redirect the user /auth/openid/ after authentication. Please make sure to configure the redirect url in your third party auth service accordingly if you're using the default vikunja frontend. -The frontend will automatically provide the API with the redirect url, composed from the current url where it's hosted. -If you want to use the desktop client with OpenID, make sure to allow redirects to `127.0.0.1`. -Take a look at the [default config file](https://kolaente.dev/vikunja/vikunja/src/branch/main/config.yml.sample) for more information about how to configure openid authentication. - -Default: `` - -Full path: `auth.openid` - -Environment path: `VIKUNJA_AUTH_OPENID` - - ---- - -## metrics - -Prometheus metrics endpoint - - - -### enabled - -If set to true, enables a /metrics endpoint for prometheus to collect metrics about Vikunja. You can query it from `/api/v1/metrics`. - -Default: `false` - -Full path: `metrics.enabled` - -Environment path: `VIKUNJA_METRICS_ENABLED` - - -### username - -If set to a non-empty value the /metrics endpoint will require this as a username via basic auth in combination with the password below. - -Default: `` - -Full path: `metrics.username` - -Environment path: `VIKUNJA_METRICS_USERNAME` - - -### password - -If set to a non-empty value the /metrics endpoint will require this as a password via basic auth in combination with the username below. - -Default: `` - -Full path: `metrics.password` - -Environment path: `VIKUNJA_METRICS_PASSWORD` - - ---- - -## defaultsettings - -Provide default settings for new users. When a new user is created, these settings will automatically be set for the user. If you change them in the config file afterwards they will not be changed back for existing users. - - - -### avatar_provider - -The avatar source for the user. Can be `gravatar`, `initials`, `upload` or `marble`. If you set this to `upload` you'll also need to specify `defaultsettings.avatar_file_id`. - -Default: `initials` - -Full path: `defaultsettings.avatar_provider` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_AVATAR_PROVIDER` - - -### avatar_file_id - -The id of the file used as avatar. - -Default: `0` - -Full path: `defaultsettings.avatar_file_id` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_AVATAR_FILE_ID` - - -### email_reminders_enabled - -If set to true users will get task reminders via email. - -Default: `false` - -Full path: `defaultsettings.email_reminders_enabled` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_EMAIL_REMINDERS_ENABLED` - - -### discoverable_by_name - -If set to true will allow other users to find this user when searching for parts of their name. - -Default: `false` - -Full path: `defaultsettings.discoverable_by_name` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_DISCOVERABLE_BY_NAME` - - -### discoverable_by_email - -If set to true will allow other users to find this user when searching for their exact email. - -Default: `false` - -Full path: `defaultsettings.discoverable_by_email` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_DISCOVERABLE_BY_EMAIL` - - -### overdue_tasks_reminders_enabled - -If set to true will send an email every day with all overdue tasks at a configured time. - -Default: `true` - -Full path: `defaultsettings.overdue_tasks_reminders_enabled` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_OVERDUE_TASKS_REMINDERS_ENABLED` - - -### overdue_tasks_reminders_time - -When to send the overdue task reminder email. - -Default: `9:00` - -Full path: `defaultsettings.overdue_tasks_reminders_time` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_OVERDUE_TASKS_REMINDERS_TIME` - - -### default_project_id - -The id of the default project. Make sure users actually have access to this project when setting this value. - -Default: `0` - -Full path: `defaultsettings.default_project_id` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_DEFAULT_PROJECT_ID` - - -### week_start - -Start of the week for the user. `0` is sunday, `1` is monday and so on. - -Default: `0` - -Full path: `defaultsettings.week_start` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_WEEK_START` - - -### language - -The language of the user interface. Must be an ISO 639-1 language code followed by an ISO 3166-1 alpha-2 country code. Check https://kolaente.dev/vikunja/vikunja/frontend/src/branch/main/src/i18n/lang for a list of possible languages. Will default to the browser language the user uses when signing up. - -Default: `` - -Full path: `defaultsettings.language` - -Environment path: `VIKUNJA_DEFAULTSETTINGS_LANGUAGE` - - -### timezone - -The time zone of each individual user. This will affect when users get reminders and overdue task emails. - -Default: `