Compare commits

...

14 Commits

Author SHA1 Message Date
k00b 1d3ab23ec4 cached fetcher delete key 2024-10-16 14:43:11 -05:00
k00b 1645c2aabf avoid dev refresh of lnd 2024-10-16 14:43:00 -05:00
Keyan ec8e775ae6
Merge pull request #1477 from stackernews/upgrade-deps
Upgrade deps
2024-10-15 12:47:56 -05:00
k00b 031d589686 disable next telemetry 2024-10-15 12:13:40 -05:00
Keyan 7d139faca1
Merge branch 'master' into upgrade-deps 2024-10-15 11:34:55 -05:00
k00b 4b18498651 hide cowboy hat -> essentials 2024-10-14 17:52:40 -05:00
k00b 2562999e85 fix mathjax single dollar conflicts 2024-10-13 10:08:54 -05:00
k00b fac70a0b94 npm audit 2024-10-12 18:28:16 -05:00
k00b 81897461e3 fix qrcode display after upgrade 2024-10-12 18:06:07 -05:00
k00b 6a8b823f9f upgrade qr code scanner and fix #1476 2024-10-12 18:06:07 -05:00
k00b f9ed1ee6f5 upgrade non-(apparently)-breaking major versions 2024-10-12 18:06:07 -05:00
k00b ff3ad7676d upgrade minor dep versions 2024-10-12 18:06:07 -05:00
k00b 9a6a167dd4 upgrade patch versions 2024-10-12 18:06:07 -05:00
k00b 021a13d21e fix anon badge 2024-10-12 18:05:45 -05:00
17 changed files with 3975 additions and 3034 deletions

View File

@ -166,3 +166,5 @@ LNBITS_WEB_PORT=5001
CPU_SHARES_IMPORTANT=1024
CPU_SHARES_MODERATE=512
CPU_SHARES_LOW=256
NEXT_TELEMETRY_DISABLED=1

View File

@ -22,3 +22,4 @@ GRAPHQL_SLOW_LOGS_MS=50
DB_APP_CONNECTION_LIMIT=4
DB_WORKER_CONNECTION_LIMIT=2
DB_TRANSACTION_TIMEOUT=10000
NEXT_TELEMETRY_DISABLED=1

View File

@ -2,11 +2,13 @@ import { cachedFetcher } from '@/lib/fetch'
import { toPositiveNumber } from '@/lib/validate'
import { authenticatedLndGrpc, getIdentity, getHeight, getWalletInfo, getNode } from 'ln-service'
const { lnd } = authenticatedLndGrpc({
const lnd = global.lnd || authenticatedLndGrpc({
cert: process.env.LND_CERT,
macaroon: process.env.LND_MACAROON,
socket: process.env.LND_SOCKET
})
}).lnd
if (process.env.NODE_ENV === 'development') global.lnd = lnd
// Check LND GRPC connection
getWalletInfo({ lnd }, (err, result) => {

View File

@ -1024,6 +1024,20 @@ export default {
return user.streak
},
gunStreak: async (user, args, { models }) => {
if (user.hideCowboyHat) {
return null
}
return user.gunStreak
},
horseStreak: async (user, args, { models }) => {
if (user.hideCowboyHat) {
return null
}
return user.horseStreak
},
maxStreak: async (user, args, { models }) => {
if (user.hideCowboyHat) {
return null

View File

@ -1,6 +1,6 @@
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/router'
import cookie from 'cookie'
import * as cookie from 'cookie'
import { useMe } from '@/components/me'
import { USER_ID, SSR } from '@/lib/constants'
import { USER } from '@/fragments/users'

View File

@ -1,4 +1,3 @@
import Badge from 'react-bootstrap/Badge'
import OverlayTrigger from 'react-bootstrap/OverlayTrigger'
import Tooltip from 'react-bootstrap/Tooltip'
import CowboyHatIcon from '@/svgs/cowboy.svg'
@ -30,12 +29,7 @@ export default function Badges ({ user, badge, className = 'ms-1', badgeClassNam
if (Number(user.id) === USER_ID.anon) {
return (
<BadgeTooltip overlayText='anonymous'>
{badge
? (
<Badge bg='grey-medium' className='ms-2 d-inline-flex align-items-center'>
<AnonIcon className={`${badgeClassName} fill-dark align-middle`} height={height} width={width} />
</Badge>)
: <span><AnonIcon className={`${badgeClassName} align-middle`} height={height} width={width} /></span>}
<span className={className}><AnonIcon className={`${badgeClassName} align-middle`} height={height} width={width} /></span>
</BadgeTooltip>
)
}

View File

@ -1,4 +1,4 @@
import QRCode from 'qrcode.react'
import { QRCodeSVG } from 'qrcode.react'
import { CopyInput, InputSkeleton } from './form'
import InvoiceStatus from './invoice-status'
import { useEffect } from 'react'
@ -25,8 +25,15 @@ export default function Qr ({ asIs, value, useWallet: automated, statusVariant,
return (
<>
<a className='d-block p-3 mx-auto' style={{ background: 'white', maxWidth: '300px' }} href={qrValue}>
<QRCode
className='h-auto mw-100' value={qrValue} renderAs='svg' size={300}
<QRCodeSVG
className='h-auto mw-100' value={qrValue} size={300} imageSettings={{
src: 'data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 256 256\'%3E%3Cpath fill-rule=\'evenodd\' d=\'m46.7 96.4 37.858 53.837-71.787 62.934L117.5 155.4l-40.075-52.854 49.412-59.492Zm156.35 41.546-49.416-58.509-34.909 116.771 44.25-67.358 58.509 59.25L241.4 47.725Z\'/%3E%3C/svg%3E',
x: undefined,
y: undefined,
height: 60,
width: 60,
excavate: true
}}
/>
</a>
{description && <div className='mt-1 text-center text-muted'>{description}</div>}

View File

@ -151,7 +151,7 @@ export const ServiceWorkerProvider = ({ children }) => {
const channel = new MessageChannel()
navigator?.serviceWorker?.controller?.postMessage({ action: ACTION_PORT }, [channel.port2])
channel.port1.onmessage = (event) => {
if (event.data.action === RESUBSCRIBE) {
if (event.data.action === RESUBSCRIBE && permission.notification === 'granted') {
return subscribeToPushNotifications()
}
}
@ -161,7 +161,7 @@ export const ServiceWorkerProvider = ({ children }) => {
navigator?.serviceWorker?.controller?.postMessage?.({ action: SYNC_SUBSCRIPTION })
logger.info('sent SYNC_SUBSCRIPTION to service worker')
navigator?.serviceWorker?.controller?.postMessage?.({ action: STORE_OS, os: detectOS() })
}, [registration])
}, [registration, permission.notification])
const contextValue = useMemo(() => ({
registration,

View File

@ -33,7 +33,7 @@ const rehypeSNStyled = () => rehypeSN({
}]
})
const remarkPlugins = [gfm, remarkMath]
const remarkPlugins = [gfm, [remarkMath, { singleDollarTextMath: false }]]
const rehypePlugins = [rehypeSNStyled, rehypeMathjax]
export function SearchText ({ text }) {

View File

@ -10,7 +10,7 @@ import { gql, useApolloClient, useMutation } from '@apollo/client'
import styles from './user-header.module.css'
import { useMe } from './me'
import { NAME_MUTATION } from '@/fragments/users'
import QRCode from 'qrcode.react'
import { QRCodeSVG } from 'qrcode.react'
import LightningIcon from '@/svgs/bolt.svg'
import { encodeLNUrl } from '@/lib/lnurl'
import Avatar from './avatar'
@ -268,7 +268,7 @@ function HeaderHeader ({ user }) {
showModal(({ onClose }) => (
<>
<a className='d-flex m-auto p-3' style={{ background: 'white', maxWidth: 'fit-content' }} href={`lightning:${lnurlp}`}>
<QRCode className='d-flex m-auto' value={lnurlp} renderAs='svg' size={300} />
<QRCodeSVG className='d-flex m-auto' value={lnurlp} size={300} />
</a>
<div className='text-center fw-bold text-muted mt-3'>click or scan</div>
</>

View File

@ -26,6 +26,10 @@ class LRUCache {
return value
}
delete (key) {
this.cache.delete(key)
}
set (key, value) {
if (this.cache.has(key)) this.cache.delete(key)
else if (this.cache.size >= this.maxSize) {

6822
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,98 +16,98 @@
"@apollo/client": "^3.11.8",
"@apollo/server": "^4.11.0",
"@as-integrations/next": "^3.1.0",
"@auth/prisma-adapter": "^1.0.3",
"@graphql-tools/schema": "^10.0.0",
"@auth/prisma-adapter": "^2.7.0",
"@graphql-tools/schema": "^10.0.6",
"@lightninglabs/lnc-web": "^0.3.2-alpha",
"@noble/curves": "^1.2.0",
"@opensearch-project/opensearch": "^2.4.0",
"@prisma/client": "^5.17.0",
"@slack/web-api": "^6.9.0",
"@noble/curves": "^1.6.0",
"@opensearch-project/opensearch": "^2.12.0",
"@prisma/client": "^5.20.0",
"@slack/web-api": "^7.6.0",
"@svgr/webpack": "^8.1.0",
"@yudiel/react-qr-scanner": "^1.1.10",
"acorn": "^8.10.0",
"ajv": "^8.12.0",
"@yudiel/react-qr-scanner": "^2.0.8",
"acorn": "^8.12.1",
"ajv": "^8.17.1",
"async-mutex": "^0.5.0",
"async-retry": "^1.3.1",
"aws-sdk": "^2.1473.0",
"async-retry": "^1.3.3",
"aws-sdk": "^2.1691.0",
"bech32": "^2.0.0",
"bolt11": "^1.4.1",
"bootstrap": "^5.3.2",
"bootstrap": "^5.3.3",
"canonical-json": "0.0.4",
"classnames": "^2.5.1",
"clipboard-copy": "^4.0.1",
"cookie": "^0.6.0",
"cookie": "^1.0.1",
"cross-fetch": "^4.0.0",
"csv-parser": "^3.0.0",
"domino": "^2.1.6",
"formik": "^2.4.5",
"formik": "^2.4.6",
"github-slugger": "^2.0.0",
"google-protobuf": "^3.21.2",
"google-protobuf": "^3.21.4",
"graphql": "^16.9.0",
"graphql-scalar": "^0.1.0",
"graphql-tag": "^2.12.6",
"graphql-type-json": "^0.3.2",
"isomorphic-ws": "^5.0.0",
"ln-service": "^57.1.3",
"ln-service": "^57.22.0",
"macaroon": "^3.0.4",
"mathjs": "^11.11.2",
"mathjs": "^13.2.0",
"mdast-util-find-and-replace": "^3.0.1",
"mdast-util-from-markdown": "^2.0.0",
"mdast-util-from-markdown": "^2.0.1",
"mdast-util-gfm": "^3.0.0",
"mdast-util-to-string": "^4.0.0",
"micromark-extension-gfm": "^3.0.0",
"next": "^13.5.7",
"next-auth": "^4.23.2",
"next": "^14.2.15",
"next-auth": "^4.24.8",
"next-plausible": "^3.12.2",
"next-seo": "^6.1.0",
"next-seo": "^6.6.0",
"node-s3-url-encode": "^0.0.4",
"nodemailer": "^6.9.6",
"nodemailer": "^6.9.15",
"nostr": "^0.2.8",
"nostr-tools": "^2.7.2",
"nostr-tools": "^2.8.0",
"nprogress": "^0.2.0",
"opentimestamps": "^0.4.9",
"page-metadata-parser": "^1.1.4",
"pg-boss": "^9.0.3",
"piexifjs": "^1.0.6",
"prisma": "^5.17.0",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-avatar-editor": "^13.0.0",
"react-bootstrap": "^2.9.0",
"react-countdown": "^2.3.5",
"react-datepicker": "^4.20.0",
"react-dom": "^18.2.0",
"prisma": "^5.20.0",
"qrcode.react": "^4.0.1",
"react": "^18.3.1",
"react-avatar-editor": "^13.0.2",
"react-bootstrap": "^2.10.5",
"react-countdown": "^2.3.6",
"react-datepicker": "^7.4.0",
"react-dom": "^18.3.1",
"react-ios-pwa-prompt": "^1.8.4",
"react-markdown": "^9.0.1",
"react-string-replace": "^1.1.1",
"react-syntax-highlighter": "^15.5.0",
"react-textarea-autosize": "^8.5.3",
"react-textarea-autosize": "^8.5.4",
"react-twitter-embed": "^4.0.4",
"react-youtube": "^10.1.0",
"recharts": "^2.9.0",
"recharts": "^2.13.0",
"rehype-mathjax": "^6.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"remove-markdown": "^0.5.0",
"sass": "^1.69.3",
"remove-markdown": "^0.5.5",
"sass": "^1.79.5",
"serviceworker-storage": "^0.1.0",
"textarea-caret": "^3.1.0",
"tldts": "^6.0.16",
"tsx": "^3.13.0",
"tldts": "^6.1.51",
"tsx": "^4.19.1",
"unist-util-visit": "^5.0.0",
"unzipper": "^0.10.14",
"unzipper": "^0.12.3",
"url-unshort": "^6.1.0",
"web-push": "^3.6.6",
"web-push": "^3.6.7",
"webln": "^0.3.2",
"webpack": "^5.89.0",
"workbox-navigation-preload": "^7.0.0",
"workbox-precaching": "^7.0.0",
"workbox-recipes": "^7.0.0",
"workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0",
"workbox-webpack-plugin": "^7.0.0",
"workbox-window": "^7.0.0",
"yup": "^1.3.2"
"webpack": "^5.95.0",
"workbox-navigation-preload": "^7.1.0",
"workbox-precaching": "^7.1.0",
"workbox-recipes": "^7.1.0",
"workbox-routing": "^7.1.0",
"workbox-strategies": "^7.1.0",
"workbox-webpack-plugin": "^7.1.0",
"workbox-window": "^7.1.0",
"yup": "^1.4.0"
},
"engines": {
"node": "18.20.4"
@ -121,10 +121,10 @@
]
},
"devDependencies": {
"@next/eslint-plugin-next": "^13.5.4",
"eslint": "^8.51.0",
"@next/eslint-plugin-next": "^14.2.15",
"eslint": "^9.12.0",
"jest": "^29.7.0",
"standard": "^17.1.0"
"standard": "^17.1.2"
},
"jest": {
"moduleNameMapper": {

View File

@ -13,7 +13,7 @@ import { datePivot } from '@/lib/time'
import { schnorr } from '@noble/curves/secp256k1'
import { notifyReferral } from '@/lib/webPush'
import { hashEmail } from '@/lib/crypto'
import cookie from 'cookie'
import * as cookie from 'cookie'
/**
* Stores userIds in user table

View File

@ -1,4 +1,4 @@
import cookie from 'cookie'
import * as cookie from 'cookie'
import { datePivot } from '../../lib/time'
/**

View File

@ -370,7 +370,7 @@ export default function Settings ({ ssrData }) {
groupClassName='mb-0'
/>
<Checkbox
label={<>hide my cowboy hat</>}
label={<>hide my cowboy essentials (e.g. cowboy hat)</>}
name='hideCowboyHat'
groupClassName='mb-0'
/>

View File

@ -22,7 +22,7 @@ import HiddenWalletSummary from '@/components/hidden-wallet-summary'
import AccordianItem from '@/components/accordian-item'
import { lnAddrOptions } from '@/lib/lnurl'
import useDebounceCallback from '@/components/use-debounce-callback'
import { QrScanner } from '@yudiel/react-qr-scanner'
import { Scanner } from '@yudiel/react-qr-scanner'
import CameraIcon from '@/svgs/camera-line.svg'
import { useShowModal } from '@/components/modal'
import { useField } from 'formik'
@ -282,17 +282,24 @@ function InvoiceScanner ({ fieldName }) {
onClick={() => {
showModal(onClose => {
return (
<QrScanner
onDecode={(result) => {
<Scanner
formats={['qr_code']}
onScan={([{ rawValue: result }]) => {
result = result.toLowerCase()
if (result.split('lightning=')[1]) {
helpers.setValue(result.split('lightning=')[1].split(/[&?]/)[0].toLowerCase())
helpers.setValue(result.split('lightning=')[1].split(/[&?]/)[0])
} else if (decode(result.replace(/^lightning:/, ''))) {
helpers.setValue(result.replace(/^lightning:/, '').toLowerCase())
helpers.setValue(result.replace(/^lightning:/, ''))
} else {
throw new Error('Not a proper lightning payment request')
}
onClose()
}}
styles={{
video: {
aspectRatio: '1 / 1'
}
}}
onError={(error) => {
if (error instanceof DOMException) {
console.log(error)