Commit Graph

873 Commits

Author SHA1 Message Date
193419d169 fix: add template send 2024-04-23 13:12:42 +07:00
6cba74e128 fix: refactor use template 2024-04-22 16:05:16 +07:00
4b90adde6b feat: download completed docs via api (#1078)
## Description

Allow users to download a completed document via API.

## Testing Performed

Tested the code locally by trying to download both draft and completed
docs. Works as expected.

## Checklist

- [x] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Implemented functionality to download signed documents directly from
the app.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-04-19 18:04:11 +07:00
fceb0eaac9 feat: update emails for self-signer (#1108)
## Description

Updated the email content based on whether the document owner is a
recipient or not.

If the document owner is a recipient (self-signer):
* the email subject will be `Please view/sign/approve your document`
* the email header will be `Please view/sign/approve your document
"<your-doc-title>"`
* the email content will be `You have initiated the document
"<your-doc-title>" that requires you to view/sign/approve it.`

Otherwise:
* the email subject will be `Please view/sign/approve this document`
* the email header will be `<doc-owner> has invited you to
view/sign/approve "<doc-title>"`
* the email content will be `<doc-owner> has invited you to
view/sign/approve the document "<doc-title>".`


## Related Issue

Related to #1091 

## Testing Performed

Tested the feature with a different number of recipients (including and
excluding the document owner - self-signer). Tested both the sending and
resending functionality.

## Checklist

- [x] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.

## UI Screenshots

![CleanShot 2024-04-18 at 12 26
11@2x](https://github.com/documenso/documenso/assets/25515812/ca80f625-befb-4cbc-a541-f2186379d2e8)
![CleanShot 2024-04-18 at 12 27
40@2x](https://github.com/documenso/documenso/assets/25515812/8bcbb6fc-ba98-4fa1-8538-2d062febd27b)
![CleanShot 2024-04-18 at 12 27
53@2x](https://github.com/documenso/documenso/assets/25515812/25d77d98-b5ec-4270-8ffa-43774fe70526)
![CleanShot 2024-04-18 at 12 30
00@2x](https://github.com/documenso/documenso/assets/25515812/a90bb8e3-3ea8-42ff-9971-559b3e81ae6f)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Enhanced the document invitation components to support scenarios where
the recipient is also the sender, providing customized email content and
subject lines.
- Introduced new properties in email templates to improve clarity and
relevance based on the user's role in the document signing process.

- **Refactor**
- Updated components to use a more flexible `headerContent` property for
displaying invitation headers, replacing previous individual inviter
details.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-04-19 17:45:33 +07:00
bd40e63392 fix: update document deletion logic (#1100) 2024-04-19 17:37:38 +07:00
6e09a4700b fix: prevent signing draft documents (#1111)
## Description

Currently users can sign and complete draft documents, which will result
in a completed document in an invalid state.

## Changes Made

- Prevent recipients from inserting or uninserting fields for draft
documents
- Prevent recipients from completing draft documents 
- Remove ability to copy signing tokens unless document is pending

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced document status visibility and control across various
components in the application. Users can now see and interact with
document statuses more dynamically in views like `DocumentPageView`,
`DocumentEditPageView`, and `DocumentsDataTable`.
- Improved document signing process with updated status checks, ensuring
actions like signing, completing, and removing fields are only available
under appropriate document statuses.

- **Bug Fixes**
- Adjusted document status validation logic in server-side operations to
prevent actions on incorrectly stated documents, enhancing the overall
security and functionality of document processing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-04-19 16:17:32 +07:00
3d3c53db02 feat: add extra info for recipient roles (#1105)
## Description

Add additional information for each role to help document owners
understand what each role involves.

## Changes Made

![CleanShot 2024-04-16 at 10 24
19](https://github.com/documenso/documenso/assets/25515812/bac6cd7d-fbe2-4987-ac17-de08db882eda)
![CleanShot 2024-04-16 at 10 24
27](https://github.com/documenso/documenso/assets/25515812/1bd23021-e971-451a-8e36-df5db57687f7)
![CleanShot 2024-04-16 at 10 24
35](https://github.com/documenso/documenso/assets/25515812/e658e86e-7fa1-4a40-9ed9-317964388e61)

## Testing Performed

Tested the changes locally.

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [x] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Updated recipient role terminology and added tooltips in the
`AddSignersFormPartial` component:
		- "Signer" changed to "Needs to sign" with tooltip
		- "Receives copy" changed to "Needs to approve" with tooltip
		- "Approver" changed to "Needs to view" with tooltip
		- "Viewer" changed to "Receives copy" with tooltip
- Enhanced select dropdown options with icons and tooltips for different
recipient roles in the `AddTemplatePlaceholderRecipients` component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Timur Ercan <timur.ercan31@gmail.com>
2024-04-17 19:36:54 +07:00
0eeccfd643 feat: add myself as signer (#1091)
## Description

This PR introduces the ability to add oneself as a signer by simply
clicking a button, rather than filling the details manually.

### "Add Myself" in the document creation flow


https://github.com/documenso/documenso/assets/25515812/0de762e3-563a-491f-a742-9078bf1d627d

### "Add Myself" in the document template creation flow


https://github.com/documenso/documenso/assets/25515812/775bae01-3f5a-4b24-abbf-a47b14ec594a


## Related Issue

Addresses
[#113](https://github.com/documenso/backlog-internal/issues/113)

## Changes Made

Added a new button that grabs the details of the logged-in user and
fills the fields *(email, name, and role)* automatically when clicked.

## Testing Performed

Tested the changes locally through the UI.

## Checklist

- [x] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced the ability for users to add themselves as signers within
documents seamlessly.
- **Enhancements**
- Improved form handling logic to accommodate new self-signer
functionality.
- Enhanced user interface elements to support the addition of self as a
signer, including a new "Add myself" button and disabling input fields
during the process.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-04-16 15:18:06 +07:00
aa4b6f1723 feat: updated mobile header (#1004)
**Description:**

- Updated mobile header with respect to latest designs 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a new `showText` property to the `MenuSwitcher` component to
control text visibility.
- Added a `textSectionClassName` property to the `AvatarWithText`
component for conditional text section styling.
- Updated the `CommandDialog` and `DialogContent` components with new
positioning and styling properties.

- **Style Updates**
- Adjusted text size responsiveness in the `Hero` component for various
screen sizes.
- Modified text truncation and input styling in the `Widget` component.
- Changed the width of the `SheetContent` element in `MobileNavigation`
and adjusted footer layout.

- **Documentation**
  - Added instructions for certificate placement in `SIGNING.md`.

- **Refactor**
- Standardized type imports across various components and utilities for
improved type checking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Adithya Krishna <adithya@documenso.com>
Signed-off-by: Adithya Krishna <aadithya794@gmail.com>
Co-authored-by: David Nguyen <davidngu28@gmail.com>
2024-04-15 15:52:34 +07:00
c8a09099a3 fix: mask recipient token (#1051)
The searchDocuments function is used for the shortcuts commands, afaik.
The function returns the documents that match the user query (if any),
alongside all their recipients.

The reason for that is so it can build the path for the document. E.g.
if you're the document owner, the document path will be
`..../documents/{id}`. But if you're a signer for example, the document
path (link) will be `..../sign/{token}`.

So instead of doing that on the frontend, I moved it to the backend.

At least that's what I understood. If I'm wrong, please correct me.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced the `CommandMenu` component to simplify search result
generation and improve document link management based on user roles.
- **Refactor**
- Updated document search logic to include recipient token masking and
refined document mapping.
- **Style**
	- Minor formatting improvement in document routing code.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-04-15 14:29:56 +07:00
0f87dc047b fix: swagger documentation authentication (#1037)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit


- **Refactor**
- Enhanced the API specification generation process to include operation
IDs, security schemes, and security definitions more efficiently.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2024-04-15 14:27:46 +07:00
8b58f10cbe feat: add cta on complete page (#1028)
![CleanShot 2024-03-18 at 11 45
40](https://github.com/documenso/documenso/assets/25515812/ae3b88de-359d-4019-866a-a76097bbb0fe)
![CleanShot 2024-03-18 at 11 46
25](https://github.com/documenso/documenso/assets/25515812/b5ff7078-623e-476c-8800-17d14bc8efa9)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a "Claim Account" feature allowing new users to sign up by
providing their name, email, and password.
- Enhanced user experience for both logged-in and non-logged-in users
with improved UI/UX and additional functionality.

- **Enhancements**
- Implemented form validation and error handling for a smoother sign-up
process.
	- Integrated analytics to track user actions during account claiming.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
Co-authored-by: David Nguyen <davidngu28@gmail.com>
2024-04-11 10:09:04 +03:00
4d4dfd3c5f fix: implement review feedback, resolve build errors 2024-04-10 17:39:16 +07:00
110f9bae12 feat: add certificate and audit log pdfs 2024-04-10 15:13:18 +07:00
8fe6533ef5 fix: document audit log field security migration (#1081)
## Description

When document audit logs were first introduced, we by default set the
`fieldSecurity` to `NONE`

Now that document auth has been added, this is causing issues since we
do not use `NONE` to define field that has no migrations required, but
rather have the `fieldSecurity` field itself be undefined.

To keeps things consistent, this migration replaces `NONE` with
undefined.

There are a few ways to approach this:
- Run a prisma migration on the JSON
- Modify the data before we pass the data to the schema in
`parseDocumentAuditLogData`
- Use `NONE` instead of undefined

If anyone thinks there's a better way to do this, please drop a comment
🙇
2024-04-09 18:48:15 +07:00
03bf16522d feat: add prefilling pdf form fields via api (#1086)
## Description

Adds the ability to prefill native PDF form fields via the API using
either normal documents or templates.

Since we won't always know when a document is uploaded and has forms we
opt to do this on creation for templates and on sending the document to
recipients in all cases. This means that for a created document it can
look a little funky since the form fields are missing the data until the
document is sent.

This should be improved in a later change but since we've scoped this to
an API only workflow for now we are less concerned with the visual
issues.

## Related Issue

N/A

## Changes Made

- Added the `formValues` field the document model
- Added a new method for finding and filling form fields based on a `key
| value` pair
- Updated the API input shapes to take the new field.

## Testing Performed

- Have created and tested a document using the API both for creation and
usage with a template.
- Have verified that the fields display as expected either during
creation or sending depending on the document type.
2024-04-08 20:55:54 +07:00
627265f016 fix: return updated doc (#1089)
## Description

Fetch the updated version of the document after sealing it and return
it. Previously, the `document.documentData.data` wasn't up to date. Now
it is.

## Related Issue

Fixes #1088.

## Testing Performed

* Added console.logs in the code to make sure it returns the proper data
* Set up a webhook and tested that the webhook receives the updated data

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [x] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.
2024-04-08 19:28:50 +07:00
08b693ff95 feat: add prefilling pdf form fields via api 2024-04-08 17:01:11 +07:00
d4a7eb299e chore: add 2FA reauth docs (#1076)
## Description

Update the tooltips to show documentation for 2FA
2024-04-04 20:18:55 +07:00
65c07032de fix: improve error log coverage (#1070)
## Description

Increase coverage of error logging in TRPC routes.
2024-04-04 11:12:06 +07:00
56c550c9d2 fix: refactor tests (#1066)
## Changes Made

- Refactor/optimise tests
- Reduce flakiness
- Add parallel tests (if there's enough CPU capacity)
- Removed explicit worker count when running parallel tests. Defaults to
50% of CPU capacity.

Might want to consider sharding the test across runners in the future as
our tests grows.
2024-04-03 16:13:35 +07:00
58481f66b8 fix: enforce 2FA for email password SSO linked accounts (#1072)
## Description

Fixed issue where accounts that were initially created via
email/password, then linked to an SSO account, can bypass the 2FA during
login if they use their email password.

## Testing Performed

Tested locally, and 2FA is now required for linked SSO accounts
2024-04-03 14:18:36 +07:00
cbe6270494 feat: add passkey and 2FA document action auth options (#1065)
## Description

Add the following document action auth options:
- 2FA
- Passkey

If the user does not have the required auth setup, we onboard them
directly.

## Changes made

Note: Added secondaryId to the VerificationToken schema

## Testing Performed

Tested locally, pending preview tests

## Checklist

- [X] I have tested these changes locally and they work as expected.
- [X] I have added/updated tests that prove the effectiveness of these
changes.
- [X] I have followed the project's coding style guidelines.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced components for 2FA, account, and passkey authentication
during document signing.
- Added "Require passkey" option to document settings and signer
authentication settings.
- Enhanced form submission and loading states for improved user
experience.
- **Refactor**
- Optimized authentication components to efficiently support multiple
authentication methods.
- **Chores**
- Updated and renamed functions and components for clarity and
consistency across the authentication system.
- Refined sorting options and database schema to support new
authentication features.
- **Bug Fixes**
- Adjusted SignInForm to verify browser support for WebAuthn before
proceeding.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-03-31 15:49:12 +08:00
b436331d7d fix: improve error log coverage 2024-03-30 14:00:34 +08:00
117d9427c3 fix: passkey login 2024-03-28 19:06:19 +08:00
7a689aecae feat: document super delete (#1023)
Added a dialog button at the bottom of the admin/documents/[id] page
with confirmation popup.

Confirmation popup have validation for reason to input.

On confirmation document is deleted, and an email is triggred to the
owner of document with the reason stated.

Let me know if there is any more requirement or correction is needed in
this pr. :) #1020
2024-03-28 14:15:06 +07:00
1c54f69a5a fix: build error from renaming 2024-03-28 07:01:57 +00:00
a56bf6a192 fix: update email template and tidy code 2024-03-28 06:55:01 +00:00
a54eb54ef7 feat: add document auth (#1029) 2024-03-28 13:13:29 +08:00
956562d3b4 fix: change flattening order 2024-03-27 23:05:40 +07:00
c644d527df fix: remove scrollbar gutter (#1063)
## Description

Currently opening modals, clicking select boxes or using anything from
radix that overlays the screen in some way will shift the screen.

This can be easily noticeable when changing the document "Period"
selector on the /documents page.

## Changes Made

Undo the gutter change for now. Can find a proper solution another time.



https://github.com/documenso/documenso/assets/20962767/5bcae576-2944-4ae5-a2c3-0589e7f61bdb
2024-03-27 19:10:12 +08:00
47cf20931a fix: normalize and flatten annotations (#1062)
This change flattens and normalizes annotation and widget layers within
the PDF document removing items that can be accidentally modified after
signing which would void the signature attached to the document.

Initially this change was just to assign to an ArcoForm object in the
document catalog if it existed but quickly turned into the above.

When annotations aren't flattened Adobe PDF will say that the signature
needs to be validated and upon doing so will become invalid due to the
annotation layers being touched.

To resolve this I set out to flatten and remove the annotations by
pulling out their normal appearances if they are present, converting
them into xobjects and then drawing those using the drawObject operator.

This resolves a critical issue the users experienced during the signing
flow when they had marked up a document using annotations in pdf
editors.
2024-03-27 17:41:26 +07:00
b491bd4db9 fix: normalize and flatten annotations 2024-03-27 17:20:52 +07:00
038370012f fix: render fields on document load (#1054)
## Description

Currently if you try to load the document edit page when fields need to
be rendered, you will not be able to see the fields until you proceed to
the next step.

This is because the fields require the document PDF to be loaded prior
to rendering them.

This PR resolves that issue by only rendering the fields after the PDF
is loaded.

## Changes Made

- Add a state to track whether the PDF is loaded
- Render the fields only after the PDF is loaded

## Testing Performed

Tested document flow manually and the fields are rendered correctly on
load.

## Checklist

- [X] I have tested these changes locally and they work as expected.
- [X] I have updated the documentation to reflect these changes, if
applicable.
2024-03-27 14:10:29 +08:00
0aa111cd6e fix: fixed the no document error 2024-03-27 09:55:30 +05:30
ba30d4368d fix: build error 2024-03-27 03:37:13 +00:00
899205dde8 Merge branch 'main' into main 2024-03-27 10:11:53 +07:00
9eaecfcef2 Merge branch 'main' of https://github.com/documenso/documenso into document-super-delete#1020 2024-03-26 20:44:47 +05:30
26141050b7 fix: document super delete function calling 2024-03-26 20:42:33 +05:30
5b4152ffc5 fix: updated the super delete file 2024-03-26 20:36:45 +05:30
bd703fb620 fix: return of document after delete 2024-03-26 19:19:02 +05:30
2296924ef6 fix: reason for delete document is changed 2024-03-26 19:01:52 +05:30
006b732edb fix: update document flow fetch logic (#1039)
## Description

**Fixes issues with mismatching state between document steps.**

For example, editing a recipient and proceeding to the next step may not
display the updated recipient. And going back will display the old
recipient instead of the updated values.

**This PR also improves mutation and query speeds by adding logic to
bypass query invalidation.**

```ts
export const trpc = createTRPCReact<AppRouter>({
  unstable_overrides: {
    useMutation: {
      async onSuccess(opts) {
        await opts.originalFn();

        // This forces mutations to wait for all the queries on the page to reload, and in
        // this case one of the queries is `searchDocument` for the command overlay, which
        // on average takes ~500ms. This means that every single mutation must wait for this.
        await opts.queryClient.invalidateQueries(); 
      },
    },
  },
});
```

I've added workarounds to allow us to bypass things such as batching and
invalidating queries. But I think we should instead remove this and
update all the mutations where a query is required for a more optimised
system.

## Example benchmarks

Using stg-app vs this preview there's an average 50% speed increase
across mutations.

**Set signer step:**
Average old speed: ~1100ms
Average new speed: ~550ms

**Set recipient step:**
Average old speed: ~1200ms
Average new speed: ~600ms

**Set fields step:**
Average old speed: ~1200ms
Average new speed: ~600ms

## Related Issue

This will resolve #470

## Changes Made

- Added ability to skip batch queries
- Added a state to store the required document data.
- Refetch the data between steps if/when required
- Optimise mutations and queries

## Checklist

- [X] I have tested these changes locally and they work as expected.
- [X] I have followed the project's coding style guidelines.

---------

Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2024-03-26 21:12:41 +08:00
5210fe2963 feat: add passkeys (#989)
## Description

Add support to login with passkeys.

Passkeys can be added via the user security settings page.

Note: Currently left out adding the type of authentication method for
the 'user security audit logs' because we're using the `signIn`
next-auth event which doesn't appear to provide the context. Will look
into it at another time.

## Changes Made

- Add passkeys to login
- Add passkeys feature flag
- Add page to manage passkeys
- Add audit logs relating to passkeys
- Updated prisma schema to support passkeys & anonymous verification
tokens

## Testing Performed

To be done.

MacOS:
- Safari  
- Chrome  
- Firefox 

Windows:
- Chrome [Untested] 
- Firefox [Untested]

Linux:
- Chrome [Untested]
- Firefox [Untested]

iOS:
- Safari 

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [X] I have tested these changes locally and they work as expected.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced Passkey authentication, including creation, sign-in, and
management of passkeys.
- Added a Passkeys section in Security Settings for managing user
passkeys.
- Implemented UI updates for Passkey authentication, including a new
dialog for creating passkeys and a data table for managing them.
- Enhanced security settings with server-side feature flags to
conditionally display new security features.
- **Bug Fixes**
	- Improved UI consistency in the Settings Security Activity Page.
- Updated button styling in the 2FA Recovery Codes component for better
visibility.
- **Refactor**
- Streamlined authentication options to include WebAuthn credentials
provider.
- **Chores**
- Updated database schema to support passkeys and related functionality.
	- Added new audit log types for passkey-related activities.
- Enhanced server-only authentication utilities for passkey registration
and management.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-03-26 21:11:59 +08:00
3eddfcc805 chore: add test for multiple recipient (#1045) 2024-03-25 13:57:32 +07:00
43400c07de feat: remove 2FA password requirement (#1053) 2024-03-25 11:34:50 +08:00
1725af71b6 chore: add test to update username (#1049) 2024-03-23 13:41:12 +08:00
c71347aeb9 S3Client: Add forcePathStyle 2024-03-22 15:46:22 +01:00
72fd1eead2 fix: use correct date format (#1046)
### Before
![CleanShot 2024-03-21 at 17 23
09@2x](https://github.com/documenso/documenso/assets/55143799/d1cd22ca-399b-4ba2-bb82-b4dc869605c8)

### After
![CleanShot 2024-03-21 at 17 23
17@2x](https://github.com/documenso/documenso/assets/55143799/cdb814ea-01be-4bcb-9bad-df41030f320a)
2024-03-22 14:25:12 +08:00
5289ae2fbc Merge branch 'main' into test/sign-redirect-url 2024-03-21 16:36:48 +00:00