users.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { api } from './client'
  2. export interface User {
  3. id: string
  4. username: string
  5. email: string
  6. role: string
  7. active: boolean
  8. lastLogin: number
  9. }
  10. export const usersApi = {
  11. /**
  12. * List users. Admin only - the endpoint requires the admin role, so a
  13. * non-admin caller gets a 403 and any caller must tolerate that.
  14. */
  15. list: async (page = 1, pageSize = 100) => {
  16. const { data } = await api.get('/users', { params: { page, pageSize } })
  17. return (data.users || []) as User[]
  18. },
  19. create: async (user: { username: string; password: string; email?: string; role?: string }) => {
  20. const { data } = await api.post('/users', user)
  21. return data as User & { personalProjectId?: string }
  22. },
  23. update: async (id: string, changes: { role?: string; active?: boolean; email?: string }) => {
  24. const { data } = await api.put(`/users/${id}`, changes)
  25. return data as User
  26. },
  27. remove: async (id: string) => {
  28. const { data } = await api.delete(`/users/${id}`)
  29. return data
  30. },
  31. /**
  32. * Changes an account's own password. The backend verifies `oldPassword`
  33. * against the account's current hash regardless of who is calling - there
  34. * is no way to set a new password for somebody else without knowing the
  35. * one they have now, so this only makes sense for `id === yourself`.
  36. */
  37. changeOwnPassword: async (id: string, oldPassword: string, newPassword: string) => {
  38. const { data } = await api.post(`/users/${id}/change-password`, { oldPassword, newPassword })
  39. return data
  40. },
  41. }
  42. export interface ProjectMember {
  43. userId: string
  44. role: 'admin' | 'editor' | 'viewer'
  45. username?: string
  46. email?: string
  47. addedAt?: number
  48. }
  49. export interface Project {
  50. _id: string
  51. name: string
  52. description?: string
  53. type: 'personal' | 'team'
  54. ownerId: string
  55. members: ProjectMember[]
  56. myRole: 'admin' | 'editor' | 'viewer' | 'none'
  57. workflowCount: number
  58. createdAt?: number
  59. /**
  60. * Anything the project carries that is not one of the fields above. Retention
  61. * lives here as `retention.ttlSeconds`, inherited by every workflow in the
  62. * project that has not set its own.
  63. */
  64. settings?: { retention?: { ttlSeconds: number } } & Record<string, any>
  65. }
  66. export const projectsApi = {
  67. list: async () => {
  68. const { data } = await api.get('/projects')
  69. return (data.projects || []) as Project[]
  70. },
  71. get: async (id: string) => {
  72. const { data } = await api.get(`/projects/${id}`)
  73. return data as Project
  74. },
  75. create: async (project: { name: string; description?: string }) => {
  76. const { data } = await api.post('/projects', project)
  77. return data as Project
  78. },
  79. update: async (
  80. id: string,
  81. changes: { name?: string; description?: string; settings?: Record<string, any> }
  82. ) => {
  83. const { data } = await api.put(`/projects/${id}`, changes)
  84. return data as Project
  85. },
  86. remove: async (id: string) => {
  87. const { data } = await api.delete(`/projects/${id}`)
  88. return data
  89. },
  90. addMember: async (id: string, userId: string, role: string) => {
  91. const { data } = await api.post(`/projects/${id}/members`, { userId, role })
  92. return data as Project
  93. },
  94. setMemberRole: async (id: string, userId: string, role: string) => {
  95. const { data } = await api.put(`/projects/${id}/members/${userId}`, { role })
  96. return data as Project
  97. },
  98. removeMember: async (id: string, userId: string) => {
  99. const { data } = await api.delete(`/projects/${id}/members/${userId}`)
  100. return data as Project
  101. },
  102. }