diff --git a/extensions/kimai/CHANGELOG.md b/extensions/kimai/CHANGELOG.md
index a741a84c812..87e2b8c5b34 100644
--- a/extensions/kimai/CHANGELOG.md
+++ b/extensions/kimai/CHANGELOG.md
@@ -1,5 +1,9 @@
# Kimai Changelog
+## [Update] - 2024-05-18
+
+Added support for API token in the extension preferences.
+
## [Fix] - 2024-03-11
Added validation of request response data to prevent breaking the extension if the data is not valid JSON.
diff --git a/extensions/kimai/README.md b/extensions/kimai/README.md
index 130f4b12f12..64e40ae6739 100644
--- a/extensions/kimai/README.md
+++ b/extensions/kimai/README.md
@@ -9,12 +9,11 @@ This [Raycast](https://raycast.com) extension lets you quickly add new time log
## Setup
-![setup](media/setup.png)
-
-To connect the extension to your Kimai instance you need to add the following settings.
+To connect the extension to your Kimai instance you need to add the following settings. There are 2 way to authorize your extension `API Token` or `Email & API Password`. `API Token` is recommended and both ways are not needed.
- **Request protocol:** Protocol to be used to make API requests. If you are using local (self hosted) Kimai, set it to 'http', otherwise keep it as 'https'.
- **Kimai Domain:** The domain of your Kimai instance like `your-organization.kimai.cloud`.
+- **API Token:** Recommended for use in extension. You can find it in your `API Access` settings.
- **Email:** Email you use to login into Kimai
- **API Password:** Password different from password you use to login into Kimai. You need to create it in your `API Access` settings.
- **Default time log duration (in minutes):** Duration that will be used to prepopulate duration field when adding new time log
@@ -23,5 +22,5 @@ You can find your settings by going to `https://{your-organization}.kimai.cloud/
1. Open Kimai dashboard
2. Click on your username
-3. Open `Password`
-4. Open `API Access`
+3. Open `API Access`
+4. Click on `+ Create` to create new token
diff --git a/extensions/kimai/media/setup.png b/extensions/kimai/media/setup.png
deleted file mode 100644
index 090caff1007..00000000000
Binary files a/extensions/kimai/media/setup.png and /dev/null differ
diff --git a/extensions/kimai/package.json b/extensions/kimai/package.json
index b58210abf59..ffeca32e08f 100644
--- a/extensions/kimai/package.json
+++ b/extensions/kimai/package.json
@@ -57,17 +57,24 @@
{
"name": "email",
"type": "textfield",
- "required": true,
+ "required": false,
"title": "Email",
"description": "Your email that you use for login in Kimai"
},
{
"name": "password",
+ "required": false,
"type": "password",
- "required": true,
"title": "API Password",
"description": "API password is different from your login password and needs to set in your profile settings"
},
+ {
+ "name": "token",
+ "type": "textfield",
+ "required": false,
+ "title": "API Token",
+ "description": "API token available in your profile settings"
+ },
{
"name": "duration",
"type": "textfield",
@@ -99,4 +106,4 @@
"pull": "npx @raycast/api@latest pull-contributions",
"publish": "npx @raycast/api@latest publish"
}
-}
+}
\ No newline at end of file
diff --git a/extensions/kimai/src/libs/api.ts b/extensions/kimai/src/libs/api.ts
index 1c7e98c5587..4bec1d146a0 100644
--- a/extensions/kimai/src/libs/api.ts
+++ b/extensions/kimai/src/libs/api.ts
@@ -47,15 +47,16 @@ const activitySchema = z.object({
});
const fetch = async (apiPath: string, init?: RequestInit | undefined) => {
- const { domain, email, password, protocol: _protocol } = getPreferences();
+ const { domain, email, password, protocol: _protocol, token } = getPreferences();
const protocol = _protocol || "https";
const response = await nodeFetch(`${protocol}://${domain}/api/${apiPath}`, {
...(init || {}),
headers: {
"Content-Type": "application/json",
- "X-AUTH-USER": email,
- "X-AUTH-TOKEN": password,
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
+ ...(!token && email ? { "X-AUTH-USER": email } : {}),
+ ...(!token && password ? { "X-AUTH-TOKEN": password } : {}),
...(init?.headers || {}),
},
});
diff --git a/extensions/kimai/src/libs/preferences.ts b/extensions/kimai/src/libs/preferences.ts
index 5ad2a380878..87475f1471c 100644
--- a/extensions/kimai/src/libs/preferences.ts
+++ b/extensions/kimai/src/libs/preferences.ts
@@ -2,8 +2,9 @@ import { getPreferenceValues } from "@raycast/api";
interface Preferences {
domain: string;
- password: string;
- email: string;
+ password?: string;
+ email?: string;
+ token?: string;
protocol?: "https" | "http";
duration: string;
}
diff --git a/extensions/kimai/src/log-time.tsx b/extensions/kimai/src/log-time.tsx
index b3d8830b597..d04a0bce7e2 100644
--- a/extensions/kimai/src/log-time.tsx
+++ b/extensions/kimai/src/log-time.tsx
@@ -1,8 +1,11 @@
import {
Action,
ActionPanel,
+ Color,
Form,
+ Icon,
LaunchType,
+ List,
PopToRootType,
Toast,
launchCommand,
@@ -27,8 +30,9 @@ interface FormValues {
const DATE_FORMAT = "YYYY-MM-DDTHH:mm:ss";
const LogTimeCommand = () => {
- const { duration } = getPreferences();
+ const { duration, email, password, token } = getPreferences();
const initialDuration = parseInt(duration);
+ const validPreferences = Boolean((email && password) || token);
const { isLoading: isLoadingProjects, projects, visitItem: visitProject } = useProjects();
const { isLoading: isLoadingActivities, activities, visitItem: visitActivity } = useActivities();
@@ -90,6 +94,17 @@ const LogTimeCommand = () => {
},
});
+ if (!validPreferences) {
+ return (
+
+
+ );
+ }
+
return (