Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Klukka
Klukka (Icelandic for clock) is a simple and easy to use Time Tracking service that allows you to track times spent an various projects in a browser.

Klukka (Icelandic for clock) is a simple and easy to use Time Tracking service that allows you to track times spent an
various projects in a browser.

## Screenshots

Expand All @@ -15,7 +17,8 @@ Klukka (Icelandic for clock) is a simple and easy to use Time Tracking service t
</table>

## Features
- Manage multiple projects with ease and track times to the second in your browser Mobile or Desktop.

- Manage multiple projects with ease and track times to the second in your browser Mobile or Desktop.
- Easily switch between projects. All your tracked times can be viewed and edited in a calendar.
- Gain insights into the times where you have spent the most time
- Export the Data as CSV
Expand All @@ -29,10 +32,12 @@ Track times and manage the data on Android with the App


## Docker
The most simple way is to run with docker-compose using the docker-compose.yaml file in the repository. Update the envirmoent variables with your own data and run docker compose up -d

The most simple way is to run with docker-compose using the docker-compose.yaml file in the repository. Update the
envirmoent variables with your own data and run docker compose up -d

## API
The API can be viewed via swagger or OpenAPI with /swagger or /open API per browser with the URL you have setup

The API can be viewed via swagger or OpenAPI with /swagger or /open API per browser with the URL you have setup

License: MIT
1 change: 1 addition & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ services:
- postgres
environment:
- APPLICATION_URL=
- JWT_SECRET= #create a secret with 'openssl rand -base64 64'
- ADMIN_USER_NAME=
- ADMIN_PASSWORD=
- DATABASE_PORT=5432
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/de/OneManProjects/Action.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@

public interface Action {

void run(Context ctx) throws SQLException, MessagingException, IOException;
void run(Context ctx) throws SQLException, MessagingException, IOException, IllegalAccessException;
}
1 change: 1 addition & 0 deletions src/main/java/de/OneManProjects/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ public <T> T fromJsonString(@NotNull final String json, @NotNull final Type targ
get("api/user/data", ctx -> runAction(ctx, Users::getUserData, true));
get("api/user/delete", ctx -> runAction(ctx, Users::deleteAccount, true));
get("api/user/listTokens", ctx -> runAction(ctx, Users::getUserTokens, true));
get("api/user/export", ctx -> runAction(ctx, Users::exportUserData, true));

post("api/group/create", ctx -> runAction(ctx, Groups::groupUserCreateGroup, true));
post("api/group/update", ctx -> runAction(ctx, Groups::groupUpdate, true));
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/de/OneManProjects/api/Admins.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class Admins {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void adminUpdateRoles(final Context ctx) throws SQLException {
public static void adminUpdateRoles(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserAdmin(ctx)) {
final User user = ctx.bodyAsClass(User.class);
final boolean res = Users.updateUserRole(user.id(), user.roles());
Expand Down Expand Up @@ -101,7 +101,7 @@ public static void adminUpdateRoles(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void adminAddNewUser(final Context ctx) throws SQLException, MessagingException, IOException {
public static void adminAddNewUser(final Context ctx) throws SQLException, MessagingException, IOException, IllegalAccessException {
if (Auth.isUserAdmin(ctx)) {
final User newUser = ctx.bodyAsClass(User.class);
final String p = Auth.createRandomPassword();
Expand Down Expand Up @@ -135,7 +135,7 @@ public static void adminAddNewUser(final Context ctx) throws SQLException, Messa
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void adminDeleteUser(final Context ctx) throws SQLException {
public static void adminDeleteUser(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserAdmin(ctx)) {
final int userToDel = ctx.bodyAsClass(Integer.class);
final boolean res1 = Users.deleteUser(userToDel);
Expand Down Expand Up @@ -166,7 +166,7 @@ public static void adminDeleteUser(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void adminDeleteGroup(final Context ctx) throws SQLException {
public static void adminDeleteGroup(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserAdmin(ctx)) {
final int groupToDelete = ctx.bodyAsClass(Integer.class);
final boolean res1 = Groups.deleteGroup(groupToDelete);
Expand All @@ -191,7 +191,7 @@ public static void adminDeleteGroup(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void getAdminData(final Context ctx) throws SQLException {
public static void getAdminData(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserAdmin(ctx)) {
Responses.setResponseOrError(ctx, Optional.of(new AdminData(Users.getAllUsers(), Groups.getAllGroups(), new ArrayList<>())), false);
} else {
Expand All @@ -214,7 +214,7 @@ public static void getAdminData(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void setPrivacyHtml(final Context ctx) throws IOException, SQLException {
public static void setPrivacyHtml(final Context ctx) throws IOException, SQLException, IllegalAccessException {
if (Auth.isUserAdmin(ctx)) {
final PrivacyInfo toUpdate = ctx.bodyAsClass(PrivacyInfo.class);
Files.writeString(PRIVACY_HTML, toUpdate.html(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Expand Down
24 changes: 12 additions & 12 deletions src/main/java/de/OneManProjects/api/Groups.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public class Groups {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void getGroupDetails(final Context ctx) throws SQLException {
public static void getGroupDetails(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userId = Auth.getUserFromContext(ctx);
final int groupId = ctx.bodyAsClass(Integer.class);
Expand Down Expand Up @@ -110,7 +110,7 @@ private static String getExportFilename(final DataFilter df, final String groupN
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void exportData(final Context ctx) throws SQLException {
public static void exportData(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final ExportFilter filter = ctx.bodyAsClass(ExportFilter.class);
if (filter.groupId().isPresent()) {
Expand Down Expand Up @@ -150,7 +150,7 @@ public static void exportData(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void getGroupDataToAnalyse(final Context ctx) throws SQLException {
public static void getGroupDataToAnalyse(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userId = Auth.getUserFromContext(ctx);
final DataFilter filter = ctx.bodyAsClass(DataFilter.class);
Expand Down Expand Up @@ -189,7 +189,7 @@ public static void getGroupDataToAnalyse(final Context ctx) throws SQLException
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupUserCreateGroup(final Context ctx) throws SQLException {
public static void groupUserCreateGroup(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final de.OneManProjects.data.Group newGroup = ctx.bodyAsClass(de.OneManProjects.data.Group.class);
Expand Down Expand Up @@ -220,7 +220,7 @@ public static void groupUserCreateGroup(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupDelete(final Context ctx) throws SQLException {
public static void groupDelete(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final int groupId = ctx.bodyAsClass(Integer.class);
Expand Down Expand Up @@ -256,7 +256,7 @@ private static boolean canUserManageGroup(final int userID, final int groupId) t
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupUserInvite(final Context ctx) throws SQLException, MessagingException {
public static void groupUserInvite(final Context ctx) throws SQLException, MessagingException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final GroupToUser groupToUser = ctx.bodyAsClass(GroupToUser.class);
Expand Down Expand Up @@ -302,7 +302,7 @@ public static void groupUserInvite(final Context ctx) throws SQLException, Messa
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupUserRemove(final Context ctx) throws SQLException {
public static void groupUserRemove(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final GroupToUser groupToUser = ctx.bodyAsClass(GroupToUser.class);
Expand Down Expand Up @@ -339,7 +339,7 @@ public static void groupUserRemove(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupAddProject(final Context ctx) throws SQLException {
public static void groupAddProject(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final Project project = ctx.bodyAsClass(Project.class);
Expand Down Expand Up @@ -373,7 +373,7 @@ public static void groupAddProject(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupUpdate(final Context ctx) throws SQLException {
public static void groupUpdate(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final de.OneManProjects.data.Group group = ctx.bodyAsClass(de.OneManProjects.data.Group.class);
Expand Down Expand Up @@ -407,7 +407,7 @@ public static void groupUpdate(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void groupDeleteProject(final Context ctx) throws SQLException {
public static void groupDeleteProject(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userID = Auth.getUserFromContext(ctx);
final IdTupel tuple = ctx.bodyAsClass(IdTupel.class);
Expand Down Expand Up @@ -436,7 +436,7 @@ public static void groupDeleteProject(final Context ctx) throws SQLException {
@OpenApiResponse(status = "403", description = "FORBIDDEN")
}
)
public static void getManagedGroups(final Context ctx) throws SQLException {
public static void getManagedGroups(final Context ctx) throws SQLException, IllegalAccessException {
if (Auth.isUserGroup(ctx)) {
final int userId = Auth.getUserFromContext(ctx);
final List<Group> groups = de.OneManProjects.database.Groups.getManagedGroups(userId);
Expand Down Expand Up @@ -465,7 +465,7 @@ public static void getManagedGroups(final Context ctx) throws SQLException {
@OpenApiResponse(status = "200", content = @OpenApiContent(from = BooleanResponse.class))
}
)
public static void userLeaveGroup(final Context ctx) throws SQLException {
public static void userLeaveGroup(final Context ctx) throws SQLException, IllegalAccessException {
final int groupId = ctx.bodyAsClass(Integer.class);
final int userId = Auth.getUserFromContext(ctx);
final boolean res = de.OneManProjects.database.Groups.leaveGroup(userId, groupId);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/de/OneManProjects/api/Logins.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static void refresh(final Context ctx) throws SQLException {
@OpenApiResponse(status = "200", description = "OK"),
}
)
public static void logout(final Context ctx) throws SQLException {
public static void logout(final Context ctx) throws SQLException, IllegalAccessException {
final int userId = Auth.getUserFromContext(ctx);
ctx.removeCookie("jwt", "/api");
ctx.removeCookie("refresh", "/api");
Expand Down
Loading
Loading