Dwayne Harris 5 years ago
parent
commit
d24f95671a
  1. 191
      package-lock.json
  2. 16
      package.json
  3. 23
      src/lib/media.ts
  4. 7
      src/plugins/api/authentication.ts
  5. 10
      src/plugins/api/groups.ts
  6. 6
      src/plugins/api/users.ts
  7. 3
      src/schemas.ts
  8. 2
      src/types/collections.ts

191
package-lock.json

@ -4,46 +4,114 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@azure/abort-controller": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.0.tgz",
"integrity": "sha512-U4RM+AuCxlwq1GDP+VSswfzxvsmQ2hUAAhii2Em2xf0e00/6CsZAoQnQCxhvLDe39pebjivobU29LioN9x+DJQ==",
"requires": {
"tslib": "^1.9.3"
}
},
"@azure/core-asynciterator-polyfill": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz",
"integrity": "sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg=="
},
"@azure/core-auth": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.0.0.tgz",
"integrity": "sha512-DcXqxt0O0HDhYTcrN16e/hJutFkFTM8fQq6bJbHuDh5AUbDUKFrF64hj5RXATukThOszGFrR1MWJOGZPSo7fiA==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-tracing": "1.0.0-preview.5",
"tslib": "^1.9.3"
}
},
"@azure/core-http": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-1.0.0.tgz",
"integrity": "sha512-vUVrALCoxY0gRfGWbEdiaFGK7qJMV/ZjZucN+LWZZGy/NdP5Iv6nVrxeb7YYIhPDsmcRvABYHrZUt01TB/8aAQ==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-auth": "^1.0.0",
"@azure/core-tracing": "1.0.0-preview.5",
"@azure/logger": "^1.0.0",
"@types/node-fetch": "^2.5.0",
"@types/tunnel": "^0.0.1",
"form-data": "^2.5.0",
"node-fetch": "^2.6.0",
"process": "^0.11.10",
"tough-cookie": "^3.0.1",
"tslib": "^1.9.3",
"tunnel": "^0.0.6",
"uuid": "^3.3.2",
"xml2js": "^0.4.19"
}
},
"@azure/core-lro": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-1.0.0.tgz",
"integrity": "sha512-l4abIb8S9qmlv3bJkonLvgGSVQcSXq5jByA7Z28GRGJaQN/mSFal9YQOuLvVag+JXQJsoftuxJFrZiggF2TwOg==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-http": "^1.0.0",
"events": "^3.0.0",
"tslib": "^1.9.3"
}
},
"@azure/core-paging": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.0.0.tgz",
"integrity": "sha512-CzaT7LwxU97PZ+/Pn7uAbNGXY2mJ/3b56kmLsZzbR9stfrNfzlILxR94WHG/D1jZEQOk4lUNiaqJ2zP7nSGJhA==",
"requires": {
"@azure/core-asynciterator-polyfill": "^1.0.0"
}
},
"@azure/core-tracing": {
"version": "1.0.0-preview.5",
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.5.tgz",
"integrity": "sha512-i3hF4EQucZmn2l4zXscwG5bilnboKHtnLMFVuzXk55dt487/9EJ5uMOP3eyTFpULGjn6xubgYFAJVpUJGVQv4w==",
"requires": {
"@opencensus/web-types": "0.0.7",
"tslib": "^1.9.3"
}
},
"@azure/cosmos": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.3.6.tgz",
"integrity": "sha512-HCPIa4lgBQnetH8VVwLJBsBipAyCt1iQRoojgtLpZBfu4pKvg2z2Vj3oyxxc5lYaab7VzLLSMynpWt/8Bixhmg==",
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.4.2.tgz",
"integrity": "sha512-dj0sR8xVv99wXcrEvnHzIFDj1d/4yV+koLih3g9k5Ec+SB405eZdp1O73oo7T4Jc00g/bY7eSC7vzNy+4D6DWw==",
"requires": {
"@types/debug": "^4.1.4",
"debug": "^4.1.1",
"fast-json-stable-stringify": "^2.0.0",
"node-abort-controller": "^1.0.4",
"node-fetch": "^2.6.0",
"os-name": "^3.1.0",
"priorityqueuejs": "^1.0.0",
"semaphore": "^1.0.5",
"tslib": "^1.9.3",
"universal-user-agent": "^4.0.0",
"uuid": "^3.3.2"
}
},
"@azure/ms-rest-js": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.0.4.tgz",
"integrity": "sha512-nSOPt6st0RtxclYBQV65qXZpvMDqiDQssktvB/SMTAJ5bIytSPtBmlttTTigO5qHvwQcfzzpQE0sMceK+dJ/IQ==",
"@azure/logger": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.0.tgz",
"integrity": "sha512-g2qLDgvmhyIxR3JVS8N67CyIOeFRKQlX/llxYJQr1OSGQqM3HTpVP8MjmjcEKbL/OIt2N9C9UFaNQuKOw1laOA==",
"requires": {
"@types/node-fetch": "^2.3.7",
"@types/tunnel": "0.0.1",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
"node-fetch": "^2.6.0",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
"uuid": "^3.3.2",
"xml2js": "^0.4.19"
"tslib": "^1.9.3"
}
},
"@azure/storage-blob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-10.5.0.tgz",
"integrity": "sha512-67+0EP7STy9BQgzvN1RgmSvXhxRd044eDgepX7zBp7XslBxz8YGo2cSLm9w5o5Qf1FLCRlwuziRMikaPCLMpVw==",
"requires": {
"@azure/ms-rest-js": "^2.0.0",
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.0.0.tgz",
"integrity": "sha512-kYR9uqbLLR8WSigtMlF3x0xa3TlDOb7p2GEPCEW1OyiXEImL0z9Iwws1o1HJuD/WidkczNXpRPjtMPyq4CYe1w==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-http": "^1.0.0",
"@azure/core-lro": "^1.0.0",
"@azure/core-paging": "^1.0.0",
"@azure/core-tracing": "1.0.0-preview.5",
"@azure/logger": "^1.0.0",
"events": "^3.0.0",
"tslib": "^1.9.3"
}
@ -54,6 +122,11 @@
"integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==",
"dev": true
},
"@opencensus/web-types": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz",
"integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g=="
},
"@types/bcryptjs": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz",
@ -66,12 +139,12 @@
"integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ=="
},
"@types/dotenv": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz",
"integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==",
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz",
"integrity": "sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==",
"dev": true,
"requires": {
"@types/node": "*"
"dotenv": "*"
}
},
"@types/jsonwebtoken": {
@ -84,9 +157,9 @@
}
},
"@types/lodash": {
"version": "4.14.144",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.144.tgz",
"integrity": "sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg==",
"version": "4.14.146",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.146.tgz",
"integrity": "sha512-JzJcmQ/ikHSv7pbvrVNKJU5j9jL9VLf3/gqs048CEnBVVVEv4kve3vLxoPHGvclutS+Il4SBIuQQ087m1eHffw==",
"dev": true
},
"@types/node": {
@ -95,9 +168,9 @@
"integrity": "sha512-vqcj1MVm2Sla4PpMfYKh1MyDN4D2f/mPIZD7RdAGqEsbE+JxfeqQHHVbRDQ0Nqn8i73gJa1HQ1Pu3+nH4Q0Yiw=="
},
"@types/node-fetch": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.0.tgz",
"integrity": "sha512-TLFRywthBgL68auWj+ziWu+vnmmcHCDFC/sqCOQf1xTz4hRq8cu79z8CtHU9lncExGBsB8fXA4TiLDLt6xvMzw==",
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.3.tgz",
"integrity": "sha512-X3TNlzZ7SuSwZsMkb5fV7GrPbVKvHc2iwHmslb8bIxRKWg2iqkfm3F/Wd79RhDpOXR7wCtKAwc5Y2JE6n/ibyw==",
"requires": {
"@types/node": "*"
}
@ -111,9 +184,9 @@
}
},
"@types/uuid": {
"version": "3.4.5",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.5.tgz",
"integrity": "sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA==",
"version": "3.4.6",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.6.tgz",
"integrity": "sha512-cCdlC/1kGEZdEglzOieLDYBxHsvEOIg7kp/2FYyVR9Pxakq+Qf/inL3RKQ+PA8gOlI/NnL+fXmQH12nwcGzsHw==",
"dev": true,
"requires": {
"@types/node": "*"
@ -125,14 +198,6 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
"abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"requires": {
"event-target-shim": "^5.0.0"
}
},
"abstract-logging": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-1.0.0.tgz",
@ -867,11 +932,6 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
},
"events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
@ -1088,11 +1148,11 @@
}
},
"fastify-cors": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fastify-cors/-/fastify-cors-2.1.3.tgz",
"integrity": "sha512-ZHFzKn1DddymsxzvdtjEQfkuMfGgwcp++FKuTTMmAN2KFB7hJRmOINffjfRdmUcgXdE4LoSy5XJROWKx/b+CPQ==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/fastify-cors/-/fastify-cors-2.2.0.tgz",
"integrity": "sha512-xnZmYPWUxrIBEsv5x2JrsDlrskoFkOE0KAwedEe6dn8TCxpARwW6U+nofAKWZMDF+dXkEslRCgrd1ixdEIkB8w==",
"requires": {
"fastify-plugin": "^1.5.0",
"fastify-plugin": "^1.6.0",
"vary": "^1.1.2"
}
},
@ -2857,9 +2917,9 @@
}
},
"pino-pretty": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-3.2.2.tgz",
"integrity": "sha512-2SP++Wbo4EsH5RpLhcsYHOR/8CMTIJWZpU0aPiVK0Wq8SrRMQ9oHQNffVK5ZyDFZMtSuTdFCVfLVNFmtFMDEeA==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-3.3.0.tgz",
"integrity": "sha512-aoQWRJscJrKG/YH8GKqvbYalp8rr0KDn/SUmt2XK7q3ovA8GTN6OqvomPan7soNXLUKuYJc4UQdh0Fx+15yQpw==",
"dev": true,
"requires": {
"@hapi/bourne": "^1.3.2",
@ -2903,6 +2963,11 @@
"resolved": "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz",
"integrity": "sha1-LuTyPCVgkT4IwHzlzN1t498sWvg="
},
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -3655,9 +3720,9 @@
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"typescript": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",
"integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==",
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz",
"integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==",
"dev": true
},
"undefsafe": {
@ -3707,14 +3772,6 @@
"crypto-random-string": "^1.0.0"
}
},
"universal-user-agent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
"integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
"requires": {
"os-name": "^3.1.0"
}
},
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",

16
package.json

@ -12,22 +12,22 @@
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/dotenv": "^6.1.1",
"@types/dotenv": "^8.2.0",
"@types/jsonwebtoken": "^8.3.5",
"@types/lodash": "^4.14.144",
"@types/uuid": "^3.4.5",
"@types/lodash": "^4.14.146",
"@types/uuid": "^3.4.6",
"nodemon": "^1.19.4",
"npm-run-all": "^4.1.5",
"pino-pretty": "^3.2.2",
"typescript": "^3.6.4"
"pino-pretty": "^3.3.0",
"typescript": "^3.7.2"
},
"dependencies": {
"@azure/cosmos": "^3.3.6",
"@azure/storage-blob": "^10.5.0",
"@azure/cosmos": "^3.4.2",
"@azure/storage-blob": "^12.0.0",
"bcryptjs": "^2.4.3",
"dotenv": "^8.2.0",
"fastify": "^2.10.0",
"fastify-cors": "^2.1.3",
"fastify-cors": "^2.2.0",
"fastify-helmet": "^3.0.2",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.15",

23
src/lib/media.ts

@ -1,31 +1,34 @@
import { Container } from '@azure/cosmos'
import { BlockBlobURL, SharedKeyCredential, Aborter, ContainerSASPermissions, generateBlobSASQueryParameters, AnonymousCredential } from '@azure/storage-blob'
import { ContainerSASPermissions, generateBlobSASQueryParameters, StorageSharedKeyCredential, BlobServiceClient } from '@azure/storage-blob'
import moment from 'moment'
import { MEDIA_PARTITION_KEY } from '../constants'
import { Media } from '../types/collections'
export function generateSAS(permissions: string, expirationMinutes: number) {
const sharedKeyCredential = new SharedKeyCredential(process.env.BLOB_STORAGE_ACCOUNT!, process.env.BLOB_STORAGE_ACCOUNT_KEY!)
const sharedKeyCredential = new StorageSharedKeyCredential(process.env.BLOB_STORAGE_ACCOUNT!, process.env.BLOB_STORAGE_ACCOUNT_KEY!)
return generateBlobSASQueryParameters({
containerName: process.env.BLOB_STORAGE_CONTAINER!,
permissions: ContainerSASPermissions.parse(permissions).toString(),
startTime: new Date(),
expiryTime: moment().add(expirationMinutes, 'm').toDate(),
permissions: ContainerSASPermissions.parse(permissions),
startsOn: new Date(),
expiresOn: moment().add(expirationMinutes, 'm').toDate(),
}, sharedKeyCredential).toString()
}
export async function deleteMedia(name: string) {
const blockBlobURL = new BlockBlobURL(
const blobServiceClient = new BlobServiceClient(
`https://${process.env.BLOB_STORAGE_ACCOUNT!}.blob.core.windows.net/${process.env.BLOB_STORAGE_CONTAINER!}/${name}`,
BlockBlobURL.newPipeline(new SharedKeyCredential(process.env.BLOB_STORAGE_ACCOUNT!, process.env.BLOB_STORAGE_ACCOUNT_KEY!))
new StorageSharedKeyCredential(process.env.BLOB_STORAGE_ACCOUNT!, process.env.BLOB_STORAGE_ACCOUNT_KEY!)
)
const containerClient = blobServiceClient.getContainerClient(process.env.BLOB_STORAGE_CONTAINER!)
containerClient.deleteBlob(name)
try {
await blockBlobURL.delete(Aborter.none)
} catch (e) {
await containerClient.deleteBlob(name)
} catch (err) {
console.error(err)
}
}

7
src/plugins/api/authentication.ts

@ -48,6 +48,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
about?: string
imageUrl?: string
coverImageUrl?: string
theme: string
group?: string
invitation?: string
}
@ -56,7 +57,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
schema: {
body: {
type: 'object',
required: ['id', 'email', 'password'],
required: ['id', 'email', 'password', 'theme'],
properties: {
id: {
type: 'string',
@ -83,6 +84,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
about: { type: 'string' },
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
theme: { type: 'string' },
group: { type: 'string' },
invitation: { type: 'string' },
},
@ -97,7 +99,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
server.post<DefaultQuery, DefaultParams, DefaultHeaders, Body>('/api/register', options, async (request, reply) => {
if (!server.database) return serverError(reply)
const { name, email, password, requiresApproval, privacy, about, imageUrl, coverImageUrl, invitation: code } = request.body
const { name, email, password, requiresApproval, privacy, about, imageUrl, coverImageUrl, theme, invitation: code } = request.body
const id = normalize(request.body.id)
const userContainer = containerFor(server.database.client, 'Users')
@ -178,6 +180,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
passwordHash: await hashPassword(password),
imageUrl,
coverImageUrl,
theme,
installations,
awards: 0,
points: 0,

10
src/plugins/api/groups.ts

@ -93,6 +93,7 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl?: string
coverImageUrl?: string
iconImageUrl?: string
theme: string
}
const options: RouteShorthandOptions = {
@ -114,6 +115,7 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
iconImageUrl: { type: 'string' },
theme: { type: 'string' },
},
},
response: {
@ -139,7 +141,7 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
if (viewer.groupId) return badRequestError(reply)
const { name, about, registration, imageUrl, coverImageUrl, iconImageUrl } = request.body
const { name, about, registration, imageUrl, coverImageUrl, iconImageUrl, theme } = request.body
const id = normalize(name)
const existingGroup = await getItem<Group>({ container: groupContainer, id })
@ -156,6 +158,7 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl,
coverImageUrl,
iconImageUrl,
theme,
status: GroupStatus.Pending,
active: true,
created: Date.now(),
@ -278,6 +281,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl?: string
coverImageUrl?: string
iconImageUrl?: string
theme?: string
}
const options: RouteShorthandOptions = {
@ -298,6 +302,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
iconImageUrl: { type: 'string' },
theme: { type: 'string' },
},
},
response: {
@ -330,6 +335,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl,
coverImageUrl,
iconImageUrl,
theme,
} = request.body
const mediaContainer = containerFor(server.database.client, 'Media')
@ -349,6 +355,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
imageUrl?: string
coverImageUrl?: string
iconImageUrl?: string
theme?: string
}
let updates: Updates = {}
@ -358,6 +365,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
if (imageUrl) updates.imageUrl = imageUrl
if (coverImageUrl) updates.coverImageUrl = coverImageUrl
if (iconImageUrl) updates.iconImageUrl = iconImageUrl
if (theme) updates.theme = theme
await groupItem.replace<Group>({
...group,

6
src/plugins/api/users.ts

@ -87,6 +87,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
privacy?: UserPrivacyType
imageUrl?: string
coverImageUrl?: string
theme?: string
}
const options: RouteShorthandOptions = {
@ -106,6 +107,7 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
},
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
theme: { type: 'string' },
},
},
response: {
@ -158,6 +160,10 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp
viewer.coverImageUrl = request.body.coverImageUrl
}
if (request.body.theme) {
viewer.theme = request.body.theme
}
await viewerItem.replace<User>(viewer)
return viewer
})

3
src/schemas.ts

@ -30,6 +30,7 @@ export const groupListingSchema: JSONSchema = {
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
iconImageUrl: { type: 'string' },
theme: { type: 'string' },
requiresApproval: { type: 'boolean' },
members: { type: 'number' },
posts: { type: 'number' },
@ -62,6 +63,7 @@ export const userSchema: JSONSchema = {
about: { type: 'string' },
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
theme: { type: 'string' },
subscriptions: {
type: 'array',
items: subscriptionSchema,
@ -146,6 +148,7 @@ export const selfSchema: JSONSchema = {
about: { type: 'string' },
imageUrl: { type: 'string' },
coverImageUrl: { type: 'string' },
theme: { type: 'string' },
requiresApproval: { type: 'boolean' },
privacy: { type: 'string' },
membership: { type: 'string' },

2
src/types/collections.ts

@ -109,6 +109,7 @@ export interface Group {
imageUrl?: string
coverImageUrl?: string
iconImageUrl?: string
theme: string
registration: GroupRegistrationType
status: GroupStatus
active: boolean
@ -177,6 +178,7 @@ export interface User {
about?: string
imageUrl?: string
coverImageUrl?: string
theme: string
email: string
emailVerified: boolean
passwordHash: string

Loading…
Cancel
Save