fix(marks): add default signer #207

Merged
enes merged 3 commits from 145-default-signer into 201-toolbox-update 2024-09-19 11:24:17 +00:00
6 changed files with 145 additions and 113 deletions
Showing only changes of commit 67c3c74515 - Show all commits

View File

@ -108,7 +108,6 @@ export const CreatePage = () => {
const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([]) const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([])
const [selectedTool, setSelectedTool] = useState<DrawTool>() const [selectedTool, setSelectedTool] = useState<DrawTool>()
const [toolbox] = useState<DrawTool[]>(DEFAULT_TOOLBOX)
/** /**
* Changes the drawing tool * Changes the drawing tool
@ -833,28 +832,36 @@ export const CreatePage = () => {
</div> </div>
<div className={`${styles.paperGroup} ${styles.toolbox}`}> <div className={`${styles.paperGroup} ${styles.toolbox}`}>
{toolbox.map((drawTool: DrawTool, index: number) => { {DEFAULT_TOOLBOX.filter((drawTool) => !drawTool.isHidden).map(
return ( (drawTool: DrawTool, index: number) => {
<div return (
key={index} <div
{...(drawTool.active && { key={index}
onClick: () => handleToolSelect(drawTool) {...(!drawTool.isComingSoon && {
})} onClick: () => handleToolSelect(drawTool)
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${!drawTool.active ? styles.comingSoon : ''} })}
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${drawTool.isComingSoon ? styles.comingSoon : ''}
`} `}
> >
<FontAwesomeIcon fontSize={'15px'} icon={drawTool.icon} /> <FontAwesomeIcon
{drawTool.label} fontSize={'15px'}
{drawTool.active ? ( icon={drawTool.icon}
<FontAwesomeIcon fontSize={'15px'} icon={faEllipsis} /> />
) : ( {drawTool.label}
<span className={styles.comingSoonPlaceholder}> {!drawTool.isComingSoon ? (
Coming soon <FontAwesomeIcon
</span> fontSize={'15px'}
)} icon={faEllipsis}
</div> />
) ) : (
})} <span className={styles.comingSoonPlaceholder}>
Coming soon
</span>
)}
</div>
)
}
)}
</div> </div>
<Button onClick={handleCreate} variant="contained"> <Button onClick={handleCreate} variant="contained">

View File

@ -31,7 +31,10 @@ export interface DrawTool {
icon: IconDefinition icon: IconDefinition
defaultValue?: string defaultValue?: string
selected?: boolean selected?: boolean
active?: boolean /** show or hide the toolbox item */
isHidden?: boolean
/** show or hide "coming soon" message on the toolbox item */
isComingSoon?: boolean
} }
export enum MarkType { export enum MarkType {

View File

@ -21,6 +21,8 @@ export const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000
export const SIGIT_RELAY = 'wss://relay.sigit.io' export const SIGIT_RELAY = 'wss://relay.sigit.io'
export const SIGIT_BLOSSOM = 'https://blossom.sigit.io'
export const DEFAULT_LOOK_UP_RELAY_LIST = [ export const DEFAULT_LOOK_UP_RELAY_LIST = [
SIGIT_RELAY, SIGIT_RELAY,
'wss://user.kindpag.es', 'wss://user.kindpag.es',

View File

@ -3,14 +3,26 @@ import { hexToNpub } from './nostr.ts'
import { Meta, SignedEventContent } from '../types' import { Meta, SignedEventContent } from '../types'
import { Event } from 'nostr-tools' import { Event } from 'nostr-tools'
import { EMPTY } from './const.ts' import { EMPTY } from './const.ts'
import { MarkType } from '../types/drawing.ts' import { DrawTool, MarkType } from '../types/drawing.ts'
import { import {
faT, faT,
faSignature, faSignature,
faBriefcase, faBriefcase,
faIdCard, faIdCard,
faClock, faClock,
fa1 fa1,
faCalendarDays,
faCheckDouble,
faCircleDot,
faCreditCard,
faHeading,
faImage,
faPaperclip,
faPhone,
faSquareCaretDown,
faSquareCheck,
faStamp,
faTableCellsLarge
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
/** /**
@ -140,115 +152,114 @@ const findOtherUserMarks = (marks: Mark[], pubkey: string): Mark[] => {
return marks.filter((mark) => mark.npub !== hexToNpub(pubkey)) return marks.filter((mark) => mark.npub !== hexToNpub(pubkey))
} }
export const DEFAULT_TOOLBOX = [ export const DEFAULT_TOOLBOX: DrawTool[] = [
{ {
identifier: MarkType.FULLNAME, identifier: MarkType.FULLNAME,
icon: faIdCard, icon: faIdCard,
label: 'Full Name', label: 'Full Name',
active: false isComingSoon: true
}, },
{ {
identifier: MarkType.JOBTITLE, identifier: MarkType.JOBTITLE,
icon: faBriefcase, icon: faBriefcase,
label: 'Job Title', label: 'Job Title',
active: false isComingSoon: true
}, },
{ {
identifier: MarkType.SIGNATURE, identifier: MarkType.SIGNATURE,
icon: faSignature, icon: faSignature,
label: 'Signature', label: 'Signature',
active: false isComingSoon: true
}, },
{ {
identifier: MarkType.DATETIME, identifier: MarkType.DATETIME,
icon: faClock, icon: faClock,
label: 'Date Time', label: 'Date Time',
active: false isComingSoon: true
}, },
{ {
identifier: MarkType.TEXT, identifier: MarkType.TEXT,
icon: faT, icon: faT,
label: 'Text', label: 'Text'
active: true
}, },
{ {
identifier: MarkType.NUMBER, identifier: MarkType.NUMBER,
icon: fa1, icon: fa1,
label: 'Number', label: 'Number',
active: false isComingSoon: true
},
{
identifier: MarkType.INITIALS,
icon: faHeading,
label: 'Initials',
isHidden: true
},
{
identifier: MarkType.DATE,
icon: faCalendarDays,
label: 'Date',
isHidden: true
},
{
identifier: MarkType.IMAGES,
icon: faImage,
label: 'Images',
isHidden: true
},
{
identifier: MarkType.CHECKBOX,
icon: faSquareCheck,
label: 'Checkbox',
isHidden: true
},
{
identifier: MarkType.MULTIPLE,
icon: faCheckDouble,
label: 'Multiple',
isHidden: true
},
{
identifier: MarkType.FILE,
icon: faPaperclip,
label: 'File',
isHidden: true
},
{
identifier: MarkType.RADIO,
icon: faCircleDot,
label: 'Radio',
isHidden: true
},
{
identifier: MarkType.SELECT,
icon: faSquareCaretDown,
label: 'Select',
isHidden: true
},
{
identifier: MarkType.CELLS,
icon: faTableCellsLarge,
label: 'Cells',
isHidden: true
},
{
identifier: MarkType.STAMP,
icon: faStamp,
label: 'Stamp',
isHidden: true
},
{
identifier: MarkType.PAYMENT,
icon: faCreditCard,
label: 'Payment',
isHidden: true
},
{
identifier: MarkType.PHONE,
icon: faPhone,
label: 'Phone',
isHidden: true
} }
// {
// identifier: MarkType.INITIALS,
// icon: faHeading,
// label: 'Initials',
// active: false
// },
// {
// identifier: MarkType.DATE,
// icon: faCalendarDays,
// label: 'Date',
// active: false
// },
// {
// identifier: MarkType.IMAGES,
// icon: faImage,
// label: 'Images',
// active: false
// },
// {
// identifier: MarkType.CHECKBOX,
// icon: faSquareCheck,
// label: 'Checkbox',
// active: false
// },
// {
// identifier: MarkType.MULTIPLE,
// icon: faCheckDouble,
// label: 'Multiple',
// active: false
// },
// {
// identifier: MarkType.FILE,
// icon: faPaperclip,
// label: 'File',
// active: false
// },
// {
// identifier: MarkType.RADIO,
// icon: faCircleDot,
// label: 'Radio',
// active: false
// },
// {
// identifier: MarkType.SELECT,
// icon: faSquareCaretDown,
// label: 'Select',
// active: false
// },
// {
// identifier: MarkType.CELLS,
// icon: faTableCellsLarge,
// label: 'Cells',
// active: false
// },
// {
// identifier: MarkType.STAMP,
// icon: faStamp,
// label: 'Stamp',
// active: false
// },
// {
// identifier: MarkType.PAYMENT,
// icon: faCreditCard,
// label: 'Payment',
// active: false
// },
// {
// identifier: MarkType.PHONE,
// icon: faPhone,
// label: 'Phone',
// active: false
// }
] ]
export const getToolboxLabelByMarkType = (markType: MarkType) => { export const getToolboxLabelByMarkType = (markType: MarkType) => {

View File

@ -16,6 +16,8 @@ import { CreateSignatureEventContent, Meta } from '../types'
import { hexToNpub, unixNow } from './nostr' import { hexToNpub, unixNow } from './nostr'
import { parseJson } from './string' import { parseJson } from './string'
import { hexToBytes } from '@noble/hashes/utils' import { hexToBytes } from '@noble/hashes/utils'
import { getHash } from './hash.ts'
import { SIGIT_BLOSSOM } from './const.ts'
/** /**
* Uploads a file to a file storage service. * Uploads a file to a file storage service.
@ -25,12 +27,18 @@ import { hexToBytes } from '@noble/hashes/utils'
*/ */
export const uploadToFileStorage = async (file: File) => { export const uploadToFileStorage = async (file: File) => {
// Define event metadata for authorization // Define event metadata for authorization
const hash = await getHash(await file.arrayBuffer())
if (!hash) {
throw new Error("Can't get file hash.")
}
const event: EventTemplate = { const event: EventTemplate = {
kind: 24242, kind: 24242,
content: 'Authorize Upload', content: 'Authorize Upload',
created_at: unixNow(), created_at: unixNow(),
tags: [ tags: [
['t', 'upload'], ['t', 'upload'],
['x', hash],
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now ['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
['name', file.name], ['name', file.name],
['size', String(file.size)] ['size', String(file.size)]
@ -47,11 +55,8 @@ export const uploadToFileStorage = async (file: File) => {
// Sign the authorization event using the dedicated key stored in user app data // Sign the authorization event using the dedicated key stored in user app data
const authEvent = finalizeEvent(event, hexToBytes(key)) const authEvent = finalizeEvent(event, hexToBytes(key))
// URL of the file storage service
const FILE_STORAGE_URL = 'https://blossom.sigit.io' // REFACTOR: should be an env
// Upload the file to the file storage service using Axios // Upload the file to the file storage service using Axios
const response = await axios.put(`${FILE_STORAGE_URL}/upload`, file, { const response = await axios.put(`${SIGIT_BLOSSOM}/upload`, file, {
headers: { headers: {
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)), // Set authorization header Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)), // Set authorization header
'Content-Type': 'application/sigit' // Set content type header 'Content-Type': 'application/sigit' // Set content type header

View File

@ -35,6 +35,7 @@ import { getDefaultRelayMap } from './relays'
import { parseJson, removeLeadingSlash } from './string' import { parseJson, removeLeadingSlash } from './string'
import { timeout } from './utils' import { timeout } from './utils'
import { getHash } from './hash' import { getHash } from './hash'
import { SIGIT_BLOSSOM } from './const.ts'
/** /**
* Generates a `d` tag for userAppData * Generates a `d` tag for userAppData
@ -723,6 +724,11 @@ const uploadUserAppDataToBlossom = async (
type: 'application/octet-stream' type: 'application/octet-stream'
}) })
const hash = await getHash(await file.arrayBuffer())
if (!hash) {
throw new Error("Can't get file hash.")
}
// Define event metadata for authorization // Define event metadata for authorization
const event: EventTemplate = { const event: EventTemplate = {
kind: 24242, kind: 24242,
@ -730,6 +736,7 @@ const uploadUserAppDataToBlossom = async (
created_at: unixNow(), created_at: unixNow(),
tags: [ tags: [
['t', 'upload'], ['t', 'upload'],
['x', hash],
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now ['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
['name', file.name], ['name', file.name],
['size', String(file.size)] ['size', String(file.size)]
@ -739,11 +746,8 @@ const uploadUserAppDataToBlossom = async (
// Finalize the event with the private key // Finalize the event with the private key
const authEvent = finalizeEvent(event, hexToBytes(privateKey)) const authEvent = finalizeEvent(event, hexToBytes(privateKey))
// URL of the file storage service
const FILE_STORAGE_URL = 'https://blossom.sigit.io'
// Upload the file to the file storage service using Axios // Upload the file to the file storage service using Axios
const response = await axios.put(`${FILE_STORAGE_URL}/upload`, file, { const response = await axios.put(`${SIGIT_BLOSSOM}/upload`, file, {
headers: { headers: {
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)) // Set authorization header Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)) // Set authorization header
} }