diff --git a/packages/api/src/resolvers/upload_files/index.ts b/packages/api/src/resolvers/upload_files/index.ts index 39720bc18..4e0c4cb63 100644 --- a/packages/api/src/resolvers/upload_files/index.ts +++ b/packages/api/src/resolvers/upload_files/index.ts @@ -5,6 +5,7 @@ import { MutationUploadFileRequestArgs, UploadFileStatus, UploadFileRequestErrorCode, + ArticleSavingRequestStatus, } from '../../generated/graphql' import { WithDataSourcesContext } from '../types' import { @@ -15,13 +16,17 @@ import path from 'path' import normalizeUrl from 'normalize-url' import { analytics } from '../../utils/analytics' import { env } from '../../env' +import { createPage } from '../../elastic/pages' +import { PageType } from '../../elastic/types' +import { generateSlug } from '../../utils/helpers' export const uploadFileRequestResolver: ResolverFn< UploadFileRequestResult, unknown, WithDataSourcesContext, MutationUploadFileRequestArgs -> = async (_obj, { input }, { models, kx, claims }) => { +> = async (_obj, { input }, ctx) => { + const { models, kx, claims } = ctx let uploadFileData: { id: string | null } = { id: null, } @@ -39,16 +44,19 @@ export const uploadFileRequestResolver: ResolverFn< }, }) + let title: string let fileName: string try { const url = normalizeUrl(new URL(input.url).href, { stripHash: true, stripWWW: false, }) + title = decodeURI(path.basename(new URL(url).pathname, '.pdf')) fileName = decodeURI(path.basename(new URL(url).pathname)).replace( /[^a-zA-Z0-9-_.]/g, '' ) + if (!fileName) { fileName = 'content.pdf' } @@ -73,6 +81,31 @@ export const uploadFileRequestResolver: ResolverFn< uploadFilePathName, input.contentType ) + + const pageId = await createPage( + { + id: '', + url: input.url, + userId: claims.uid, + title: title, + hash: uploadFilePathName, + content: '', + pageType: PageType.File, + uploadFileId: uploadFileData.id, + slug: generateSlug(uploadFilePathName), + createdAt: new Date(), + savedAt: new Date(), + readingProgressPercent: 0, + readingProgressAnchorIndex: 0, + state: ArticleSavingRequestStatus.Processing, + }, + ctx + ) + + if (!pageId) { + return { errorCodes: [UploadFileRequestErrorCode.FailedCreate] } + } + return { id: uploadFileData.id, uploadSignedUrl } } else { return { errorCodes: [UploadFileRequestErrorCode.FailedCreate] } diff --git a/packages/api/src/routers/svc/content.ts b/packages/api/src/routers/svc/content.ts index efde65410..30956b323 100644 --- a/packages/api/src/routers/svc/content.ts +++ b/packages/api/src/routers/svc/content.ts @@ -8,6 +8,10 @@ import { } from '../../datalayer/pubsub' import { Page } from '../../elastic/types' import { getPageByParam, updatePage } from '../../elastic/pages' +import { ArticleSavingRequestStatus } from '../../generated/graphql' +import { initModels } from '../../server' +import { kx } from '../../datalayer/knex_config' +import { setClaims } from '../../datalayer/helpers' interface UpdateContentMessage { fileId: string @@ -65,6 +69,22 @@ export function contentServiceRouter() { if (msg.author) pageToUpdate.author = msg.author if (msg.description) pageToUpdate.description = msg.description + // This event is fired after the file is fully uploaded, + // so along with upadting content, we mark it as + // succeeded. + pageToUpdate.state = ArticleSavingRequestStatus.Succeeded + + try { + const models = initModels(kx, false) + const uploadFileData = await kx.transaction(async (tx) => { + await setClaims(tx, page.userId) + return models.uploadFile.setFileUploadComplete(fileId, tx) + }) + console.log('updated uploadFileData', uploadFileData) + } catch (error) { + console.log('error marking file upload as completed', error) + } + const result = await updatePage(page.id, pageToUpdate, { pubsub: createPubSubClient(), uid: page.userId, diff --git a/packages/api/src/services/save_file.ts b/packages/api/src/services/save_file.ts index 874ca8e1d..cc7688b34 100644 --- a/packages/api/src/services/save_file.ts +++ b/packages/api/src/services/save_file.ts @@ -31,9 +31,9 @@ export const saveFile = async ( ): Promise => { console.log('saving file with input', input) - /* We do not trust the values from client, lookup upload file by querying - * with filtering on user ID and URL to verify client's uploadFileId is valid. - */ + // /* We do not trust the values from client, lookup upload file by querying + // * with filtering on user ID and URL to verify client's uploadFileId is valid. + // */ const uploadFile = await ctx.models.uploadFile.getWhere({ id: input.uploadFileId, userId: saver.id, @@ -53,63 +53,63 @@ export const saveFile = async ( return ctx.models.uploadFile.setFileUploadComplete(input.uploadFileId, tx) }) - if (!uploadFileData || !uploadFileData.id || !uploadFileData.fileName) { - console.log('error completing upload file request', input) - return { - errorCodes: [SaveErrorCode.Unknown], - } - } + // if (!uploadFileData || !uploadFileData.id || !uploadFileData.fileName) { + // console.log('error completing upload file request', input) + // return { + // errorCodes: [SaveErrorCode.Unknown], + // } + // } - const uploadFileUrlOverride = await makeStorageFilePublic( - uploadFileData.id, - uploadFileData.fileName - ) + // // const uploadFileUrlOverride = await makeStorageFilePublic( + // // uploadFileData.id, + // // uploadFileData.fileName + // // ) - const matchedUserArticleRecord = await getPageByParam({ - userId: saver.id, - url: uploadFileUrlOverride, - state: ArticleSavingRequestStatus.Succeeded, - }) + // const matchedUserArticleRecord = await getPageByParam({ + // userId: saver.id, + // url: uploadFileData.url, + // state: ArticleSavingRequestStatus.Succeeded, + // }) - if (matchedUserArticleRecord) { - await updatePage( - matchedUserArticleRecord.id, - { - savedAt: new Date(), - archivedAt: null, - }, - ctx - ) - input.clientRequestId = matchedUserArticleRecord.id - } else { - const pageId = await createPage( - { - url: uploadFileUrlOverride, - title: uploadFile.fileName, - hash: uploadFileDetails.md5Hash, - content: '', - pageType: PageType.File, - uploadFileId: input.uploadFileId, - slug: generateSlug(uploadFile.fileName), - userId: saver.id, - id: input.clientRequestId, - createdAt: new Date(), - savedAt: new Date(), - readingProgressPercent: 0, - readingProgressAnchorIndex: 0, - state: ArticleSavingRequestStatus.Succeeded, - }, - ctx - ) + // if (matchedUserArticleRecord) { + // await updatePage( + // matchedUserArticleRecord.id, + // { + // savedAt: new Date(), + // archivedAt: null, + // }, + // ctx + // ) + // input.clientRequestId = matchedUserArticleRecord.id + // } else { + // const pageId = await createPage( + // { + // url: uploadFile.url, + // title: uploadFile.fileName, + // hash: uploadFileDetails.md5Hash, + // content: '', + // pageType: PageType.File, + // uploadFileId: input.uploadFileId, + // slug: generateSlug(uploadFile.fileName), + // userId: saver.id, + // id: input.clientRequestId, + // createdAt: new Date(), + // savedAt: new Date(), + // readingProgressPercent: 0, + // readingProgressAnchorIndex: 0, + // state: ArticleSavingRequestStatus.Succeeded, + // }, + // ctx + // ) - if (!pageId) { - console.log('error creating page in elastic', input) - return { - errorCodes: [SaveErrorCode.Unknown], - } - } - input.clientRequestId = pageId - } + // if (!pageId) { + // console.log('error creating page in elastic', input) + // return { + // errorCodes: [SaveErrorCode.Unknown], + // } + // } + // input.clientRequestId = pageId + // } return { clientRequestId: input.clientRequestId,