db + auth routes

This commit is contained in:
boufni95 2024-09-16 15:15:52 +00:00
parent d2b2418e21
commit 6df5752d46
17 changed files with 553 additions and 12 deletions

View file

@ -28,6 +28,11 @@ The nostr server will send back a message response, and inside the body there wi
- input: [AuthAppRequest](#AuthAppRequest)
- output: [AuthApp](#AuthApp)
- AuthorizeDebit
- auth type: __User__
- input: [DebitAuthorization](#DebitAuthorization)
- output: [AuthorizedDebit](#AuthorizedDebit)
- BanUser
- auth type: __Admin__
- input: [BanUserRequest](#BanUserRequest)
@ -58,6 +63,11 @@ The nostr server will send back a message response, and inside the body there wi
- input: [AppsMetricsRequest](#AppsMetricsRequest)
- output: [AppsMetrics](#AppsMetrics)
- GetAuthorizedDebits
- auth type: __User__
- This methods has an __empty__ __request__ body
- output: [AuthorizedDebits](#AuthorizedDebits)
- GetHttpCreds
- auth type: __User__
- This methods has an __empty__ __request__ body
@ -170,6 +180,11 @@ The nostr server will send back a message response, and inside the body there wi
- input: [PayInvoiceRequest](#PayInvoiceRequest)
- output: [PayInvoiceResponse](#PayInvoiceResponse)
- RemoveAuthorizedDebit
- auth type: __User__
- input: [RemoveAuthorizedDebitRequest](#RemoveAuthorizedDebitRequest)
- This methods has an __empty__ __response__ body
- UseInviteLink
- auth type: __GuestWithPub__
- input: [UseInviteLinkRequest](#UseInviteLinkRequest)
@ -256,6 +271,13 @@ The nostr server will send back a message response, and inside the body there wi
- input: [AuthAppRequest](#AuthAppRequest)
- output: [AuthApp](#AuthApp)
- AuthorizeDebit
- auth type: __User__
- http method: __post__
- http route: __/api/user/debit/authorize__
- input: [DebitAuthorization](#DebitAuthorization)
- output: [AuthorizedDebit](#AuthorizedDebit)
- BanUser
- auth type: __Admin__
- http method: __post__
@ -326,6 +348,13 @@ The nostr server will send back a message response, and inside the body there wi
- input: [AppsMetricsRequest](#AppsMetricsRequest)
- output: [AppsMetrics](#AppsMetrics)
- GetAuthorizedDebits
- auth type: __User__
- http method: __get__
- http route: __/api/user/debit/get__
- This methods has an __empty__ __request__ body
- output: [AuthorizedDebits](#AuthorizedDebits)
- GetHttpCreds
- auth type: __User__
- http method: __post__
@ -545,6 +574,13 @@ The nostr server will send back a message response, and inside the body there wi
- input: [PayInvoiceRequest](#PayInvoiceRequest)
- output: [PayInvoiceResponse](#PayInvoiceResponse)
- RemoveAuthorizedDebit
- auth type: __User__
- http method: __post__
- http route: __/api/user/debit/remove__
- input: [RemoveAuthorizedDebitRequest](#RemoveAuthorizedDebitRequest)
- This methods has an __empty__ __response__ body
- RequestNPubLinkingToken
- auth type: __App__
- http method: __post__
@ -675,6 +711,14 @@ The nostr server will send back a message response, and inside the body there wi
- __allow_user_creation__: _boolean_ *this field is optional
- __name__: _string_
### AuthorizedDebit
- __debit_id__: _string_
- __debit_type__: _[AuthorizedDebitType](#AuthorizedDebitType)_
- __key__: _string_
### AuthorizedDebits
- __debits__: ARRAY of: _[AuthorizedDebit](#AuthorizedDebit)_
### BanUserRequest
- __user_id__: _string_
@ -702,6 +746,9 @@ The nostr server will send back a message response, and inside the body there wi
### CreateOneTimeInviteLinkResponse
- __invitation_link__: _string_
### DebitAuthorization
- __authorize_npub__: _string_ *this field is optional
### DecodeInvoiceRequest
- __invoice__: _string_
@ -903,6 +950,9 @@ The nostr server will send back a message response, and inside the body there wi
### RelaysMigration
- __relays__: ARRAY of: _string_
### RemoveAuthorizedDebitRequest
- __debit_id__: _string_
### RequestNPubLinkingTokenRequest
- __user_identifier__: _string_
@ -1003,6 +1053,10 @@ The nostr server will send back a message response, and inside the body there wi
- __TAPROOT_PUBKEY__
- __WITNESS_PUBKEY_HASH__
### AuthorizedDebitType
- __KEY__
- __NPUB__
### UserOperationType
- __INCOMING_INVOICE__
- __INCOMING_TX__

View file

@ -166,6 +166,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})
if (!opts.allowNotImplementedMethods && !methods.AuthorizeDebit) throw new Error('method: AuthorizeDebit is not implemented')
app.post('/api/user/debit/authorize', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'AuthorizeDebit', batch: false, nostr: false, batchSize: 0}
const stats: Types.RequestStats = { startMs:req.startTimeMs || 0, start:req.startTime || 0n, parse: process.hrtime.bigint(), guard: 0n, validate: 0n, handle: 0n }
let authCtx: Types.AuthContext = {}
try {
if (!methods.AuthorizeDebit) throw new Error('method: AuthorizeDebit is not implemented')
const authContext = await opts.UserAuthGuard(req.headers['authorization'])
authCtx = authContext
stats.guard = process.hrtime.bigint()
const request = req.body
const error = Types.DebitAuthorizationValidate(request)
stats.validate = process.hrtime.bigint()
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback)
const query = req.query
const params = req.params
const response = await methods.AuthorizeDebit({rpcName:'AuthorizeDebit', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res.json({status: 'OK', ...response})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})
if (!opts.allowNotImplementedMethods && !methods.BanUser) throw new Error('method: BanUser is not implemented')
app.post('/api/admin/user/ban', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'BanUser', batch: false, nostr: false, batchSize: 0}
@ -221,6 +243,18 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'AuthorizeDebit':
if (!methods.AuthorizeDebit) {
throw new Error('method AuthorizeDebit not found' )
} else {
const error = Types.DebitAuthorizationValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
const res = await methods.AuthorizeDebit({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'DecodeInvoice':
if (!methods.DecodeInvoice) {
throw new Error('method DecodeInvoice not found' )
@ -245,6 +279,16 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetAuthorizedDebits':
if (!methods.GetAuthorizedDebits) {
throw new Error('method GetAuthorizedDebits not found' )
} else {
opStats.validate = opStats.guard
const res = await methods.GetAuthorizedDebits({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetLNURLChannelLink':
if (!methods.GetLNURLChannelLink) {
throw new Error('method GetLNURLChannelLink not found' )
@ -379,6 +423,18 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'RemoveAuthorizedDebit':
if (!methods.RemoveAuthorizedDebit) {
throw new Error('method RemoveAuthorizedDebit not found' )
} else {
const error = Types.RemoveAuthorizedDebitRequestValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
await methods.RemoveAuthorizedDebit({...operation, ctx}); responses.push({ status: 'OK' })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'UserHealth':
if (!methods.UserHealth) {
throw new Error('method UserHealth not found' )
@ -572,6 +628,25 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})
if (!opts.allowNotImplementedMethods && !methods.GetAuthorizedDebits) throw new Error('method: GetAuthorizedDebits is not implemented')
app.get('/api/user/debit/get', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetAuthorizedDebits', batch: false, nostr: false, batchSize: 0}
const stats: Types.RequestStats = { startMs:req.startTimeMs || 0, start:req.startTime || 0n, parse: process.hrtime.bigint(), guard: 0n, validate: 0n, handle: 0n }
let authCtx: Types.AuthContext = {}
try {
if (!methods.GetAuthorizedDebits) throw new Error('method: GetAuthorizedDebits is not implemented')
const authContext = await opts.UserAuthGuard(req.headers['authorization'])
authCtx = authContext
stats.guard = process.hrtime.bigint()
stats.validate = stats.guard
const query = req.query
const params = req.params
const response = await methods.GetAuthorizedDebits({rpcName:'GetAuthorizedDebits', ctx:authContext })
stats.handle = process.hrtime.bigint()
res.json({status: 'OK', ...response})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})
if (!opts.allowNotImplementedMethods && !methods.GetInviteLinkState) throw new Error('method: GetInviteLinkState is not implemented')
app.post('/api/admin/app/invite/get', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetInviteLinkState', batch: false, nostr: false, batchSize: 0}
@ -1102,6 +1177,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})
if (!opts.allowNotImplementedMethods && !methods.RemoveAuthorizedDebit) throw new Error('method: RemoveAuthorizedDebit is not implemented')
app.post('/api/user/debit/remove', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'RemoveAuthorizedDebit', batch: false, nostr: false, batchSize: 0}
const stats: Types.RequestStats = { startMs:req.startTimeMs || 0, start:req.startTime || 0n, parse: process.hrtime.bigint(), guard: 0n, validate: 0n, handle: 0n }
let authCtx: Types.AuthContext = {}
try {
if (!methods.RemoveAuthorizedDebit) throw new Error('method: RemoveAuthorizedDebit is not implemented')
const authContext = await opts.UserAuthGuard(req.headers['authorization'])
authCtx = authContext
stats.guard = process.hrtime.bigint()
const request = req.body
const error = Types.RemoveAuthorizedDebitRequestValidate(request)
stats.validate = process.hrtime.bigint()
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback)
const query = req.query
const params = req.params
await methods.RemoveAuthorizedDebit({rpcName:'RemoveAuthorizedDebit', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res.json({status: 'OK'})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
})
if (!opts.allowNotImplementedMethods && !methods.RequestNPubLinkingToken) throw new Error('method: RequestNPubLinkingToken is not implemented')
app.post('/api/app/user/npub/token', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'RequestNPubLinkingToken', batch: false, nostr: false, batchSize: 0}

View file

@ -101,6 +101,20 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
AuthorizeDebit: async (request: Types.DebitAuthorization): Promise<ResultError | ({ status: 'OK' }& Types.AuthorizedDebit)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/debit/authorize'
const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
const result = data
if(!params.checkResult) return { status: 'OK', ...result }
const error = Types.AuthorizedDebitValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
BanUser: async (request: Types.BanUserRequest): Promise<ResultError | ({ status: 'OK' }& Types.BanUserResponse)> => {
const auth = await params.retrieveAdminAuth()
if (auth === null) throw new Error('retrieveAdminAuth() returned null')
@ -232,6 +246,20 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetAuthorizedDebits: async (): Promise<ResultError | ({ status: 'OK' }& Types.AuthorizedDebits)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/debit/get'
const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
const result = data
if(!params.checkResult) return { status: 'OK', ...result }
const error = Types.AuthorizedDebitsValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetHttpCreds: async (cb: (v:ResultError | ({ status: 'OK' }& Types.HttpCreds)) => void): Promise<void> => { throw new Error('http streams are not supported')},
GetInviteLinkState: async (request: Types.GetInviteTokenStateRequest): Promise<ResultError | ({ status: 'OK' }& Types.GetInviteTokenStateResponse)> => {
const auth = await params.retrieveAdminAuth()
@ -601,6 +629,17 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
RemoveAuthorizedDebit: async (request: Types.RemoveAuthorizedDebitRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/debit/remove'
const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
return data
}
return { status: 'ERROR', reason: 'invalid response' }
},
RequestNPubLinkingToken: async (request: Types.RequestNPubLinkingTokenRequest): Promise<ResultError | ({ status: 'OK' }& Types.RequestNPubLinkingTokenResponse)> => {
const auth = await params.retrieveAppAuth()
if (auth === null) throw new Error('retrieveAppAuth() returned null')

View file

@ -57,6 +57,21 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
AuthorizeDebit: async (request: Types.DebitAuthorization): Promise<ResultError | ({ status: 'OK' }& Types.AuthorizedDebit)> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
const nostrRequest: NostrRequest = {}
nostrRequest.body = request
const data = await send(params.pubDestination, {rpcName:'AuthorizeDebit',authIdentifier:auth, ...nostrRequest })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
const result = data
if(!params.checkResult) return { status: 'OK', ...result }
const error = Types.AuthorizedDebitValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
BanUser: async (request: Types.BanUserRequest): Promise<ResultError | ({ status: 'OK' }& Types.BanUserResponse)> => {
const auth = await params.retrieveNostrAdminAuth()
if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null')
@ -140,6 +155,20 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetAuthorizedDebits: async (): Promise<ResultError | ({ status: 'OK' }& Types.AuthorizedDebits)> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
const nostrRequest: NostrRequest = {}
const data = await send(params.pubDestination, {rpcName:'GetAuthorizedDebits',authIdentifier:auth, ...nostrRequest })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
const result = data
if(!params.checkResult) return { status: 'OK', ...result }
const error = Types.AuthorizedDebitsValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetHttpCreds: async (cb: (res:ResultError | ({ status: 'OK' }& Types.HttpCreds)) => void): Promise<void> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
@ -460,6 +489,18 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
RemoveAuthorizedDebit: async (request: Types.RemoveAuthorizedDebitRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
const nostrRequest: NostrRequest = {}
nostrRequest.body = request
const data = await send(params.pubDestination, {rpcName:'RemoveAuthorizedDebit',authIdentifier:auth, ...nostrRequest })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
return data
}
return { status: 'ERROR', reason: 'invalid response' }
},
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveNostrGuestWithPubAuth()
if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null')

View file

@ -80,6 +80,22 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break
case 'AuthorizeDebit':
try {
if (!methods.AuthorizeDebit) throw new Error('method: AuthorizeDebit is not implemented')
const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier)
stats.guard = process.hrtime.bigint()
authCtx = authContext
const request = req.body
const error = Types.DebitAuthorizationValidate(request)
stats.validate = process.hrtime.bigint()
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback)
const response = await methods.AuthorizeDebit({rpcName:'AuthorizeDebit', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res({status: 'OK', ...response})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break
case 'BanUser':
try {
if (!methods.BanUser) throw new Error('method: BanUser is not implemented')
@ -127,6 +143,18 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'AuthorizeDebit':
if (!methods.AuthorizeDebit) {
throw new Error('method not defined: AuthorizeDebit')
} else {
const error = Types.DebitAuthorizationValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
const res = await methods.AuthorizeDebit({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'DecodeInvoice':
if (!methods.DecodeInvoice) {
throw new Error('method not defined: DecodeInvoice')
@ -151,6 +179,16 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetAuthorizedDebits':
if (!methods.GetAuthorizedDebits) {
throw new Error('method not defined: GetAuthorizedDebits')
} else {
opStats.validate = opStats.guard
const res = await methods.GetAuthorizedDebits({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetLNURLChannelLink':
if (!methods.GetLNURLChannelLink) {
throw new Error('method not defined: GetLNURLChannelLink')
@ -285,6 +323,18 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'RemoveAuthorizedDebit':
if (!methods.RemoveAuthorizedDebit) {
throw new Error('method not defined: RemoveAuthorizedDebit')
} else {
const error = Types.RemoveAuthorizedDebitRequestValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
await methods.RemoveAuthorizedDebit({...operation, ctx}); responses.push({ status: 'OK' })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'UserHealth':
if (!methods.UserHealth) {
throw new Error('method not defined: UserHealth')
@ -369,6 +419,19 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break
case 'GetAuthorizedDebits':
try {
if (!methods.GetAuthorizedDebits) throw new Error('method: GetAuthorizedDebits is not implemented')
const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier)
stats.guard = process.hrtime.bigint()
authCtx = authContext
stats.validate = stats.guard
const response = await methods.GetAuthorizedDebits({rpcName:'GetAuthorizedDebits', ctx:authContext })
stats.handle = process.hrtime.bigint()
res({status: 'OK', ...response})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break
case 'GetHttpCreds':
try {
if (!methods.GetHttpCreds) throw new Error('method: GetHttpCreds is not implemented')
@ -688,6 +751,22 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break
case 'RemoveAuthorizedDebit':
try {
if (!methods.RemoveAuthorizedDebit) throw new Error('method: RemoveAuthorizedDebit is not implemented')
const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier)
stats.guard = process.hrtime.bigint()
authCtx = authContext
const request = req.body
const error = Types.RemoveAuthorizedDebitRequestValidate(request)
stats.validate = process.hrtime.bigint()
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback)
await methods.RemoveAuthorizedDebit({rpcName:'RemoveAuthorizedDebit', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res({status: 'OK'})
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
break
case 'UseInviteLink':
try {
if (!methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented')

View file

@ -34,8 +34,8 @@ export type UserContext = {
app_user_id: string
user_id: string
}
export type UserMethodInputs = AddProduct_Input | DecodeInvoice_Input | EnrollAdminToken_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetPaymentState_Input | GetUserInfo_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | OpenChannel_Input | PayAddress_Input | PayInvoice_Input | UserHealth_Input
export type UserMethodOutputs = AddProduct_Output | DecodeInvoice_Output | EnrollAdminToken_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | OpenChannel_Output | PayAddress_Output | PayInvoice_Output | UserHealth_Output
export type UserMethodInputs = AddProduct_Input | AuthorizeDebit_Input | DecodeInvoice_Input | EnrollAdminToken_Input | GetAuthorizedDebits_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetPaymentState_Input | GetUserInfo_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | OpenChannel_Input | PayAddress_Input | PayInvoice_Input | RemoveAuthorizedDebit_Input | UserHealth_Input
export type UserMethodOutputs = AddProduct_Output | AuthorizeDebit_Output | DecodeInvoice_Output | EnrollAdminToken_Output | GetAuthorizedDebits_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | OpenChannel_Output | PayAddress_Output | PayInvoice_Output | RemoveAuthorizedDebit_Output | UserHealth_Output
export type AuthContext = AdminContext | AppContext | GuestContext | GuestWithPubContext | MetricsContext | UserContext
export type AddApp_Input = {rpcName:'AddApp', req: AddAppRequest}
@ -56,6 +56,9 @@ export type AddProduct_Output = ResultError | ({ status: 'OK' } & Product)
export type AuthApp_Input = {rpcName:'AuthApp', req: AuthAppRequest}
export type AuthApp_Output = ResultError | ({ status: 'OK' } & AuthApp)
export type AuthorizeDebit_Input = {rpcName:'AuthorizeDebit', req: DebitAuthorization}
export type AuthorizeDebit_Output = ResultError | ({ status: 'OK' } & AuthorizedDebit)
export type BanUser_Input = {rpcName:'BanUser', req: BanUserRequest}
export type BanUser_Output = ResultError | ({ status: 'OK' } & BanUserResponse)
@ -86,6 +89,9 @@ export type GetAppUserLNURLInfo_Output = ResultError | ({ status: 'OK' } & Lnurl
export type GetAppsMetrics_Input = {rpcName:'GetAppsMetrics', req: AppsMetricsRequest}
export type GetAppsMetrics_Output = ResultError | ({ status: 'OK' } & AppsMetrics)
export type GetAuthorizedDebits_Input = {rpcName:'GetAuthorizedDebits'}
export type GetAuthorizedDebits_Output = ResultError | ({ status: 'OK' } & AuthorizedDebits)
export type GetHttpCreds_Input = {rpcName:'GetHttpCreds', cb:(res: HttpCreds, err:Error|null)=> void}
export type GetHttpCreds_Output = ResultError | { status: 'OK' }
@ -195,6 +201,9 @@ export type PayAppUserInvoice_Output = ResultError | ({ status: 'OK' } & PayInvo
export type PayInvoice_Input = {rpcName:'PayInvoice', req: PayInvoiceRequest}
export type PayInvoice_Output = ResultError | ({ status: 'OK' } & PayInvoiceResponse)
export type RemoveAuthorizedDebit_Input = {rpcName:'RemoveAuthorizedDebit', req: RemoveAuthorizedDebitRequest}
export type RemoveAuthorizedDebit_Output = ResultError | { status: 'OK' }
export type RequestNPubLinkingToken_Input = {rpcName:'RequestNPubLinkingToken', req: RequestNPubLinkingTokenRequest}
export type RequestNPubLinkingToken_Output = ResultError | ({ status: 'OK' } & RequestNPubLinkingTokenResponse)
@ -229,6 +238,7 @@ export type ServerMethods = {
AddAppUserInvoice?: (req: AddAppUserInvoice_Input & {ctx: AppContext }) => Promise<NewInvoiceResponse>
AddProduct?: (req: AddProduct_Input & {ctx: UserContext }) => Promise<Product>
AuthApp?: (req: AuthApp_Input & {ctx: AdminContext }) => Promise<AuthApp>
AuthorizeDebit?: (req: AuthorizeDebit_Input & {ctx: UserContext }) => Promise<AuthorizedDebit>
BanUser?: (req: BanUser_Input & {ctx: AdminContext }) => Promise<BanUserResponse>
CreateOneTimeInviteLink?: (req: CreateOneTimeInviteLink_Input & {ctx: AdminContext }) => Promise<CreateOneTimeInviteLinkResponse>
DecodeInvoice?: (req: DecodeInvoice_Input & {ctx: UserContext }) => Promise<DecodeInvoiceResponse>
@ -238,6 +248,7 @@ export type ServerMethods = {
GetAppUser?: (req: GetAppUser_Input & {ctx: AppContext }) => Promise<AppUser>
GetAppUserLNURLInfo?: (req: GetAppUserLNURLInfo_Input & {ctx: AppContext }) => Promise<LnurlPayInfoResponse>
GetAppsMetrics?: (req: GetAppsMetrics_Input & {ctx: MetricsContext }) => Promise<AppsMetrics>
GetAuthorizedDebits?: (req: GetAuthorizedDebits_Input & {ctx: UserContext }) => Promise<AuthorizedDebits>
GetHttpCreds?: (req: GetHttpCreds_Input & {ctx: UserContext }) => Promise<void>
GetInviteLinkState?: (req: GetInviteLinkState_Input & {ctx: AdminContext }) => Promise<GetInviteTokenStateResponse>
GetLNURLChannelLink?: (req: GetLNURLChannelLink_Input & {ctx: UserContext }) => Promise<LnurlLinkResponse>
@ -267,6 +278,7 @@ export type ServerMethods = {
PayAddress?: (req: PayAddress_Input & {ctx: UserContext }) => Promise<PayAddressResponse>
PayAppUserInvoice?: (req: PayAppUserInvoice_Input & {ctx: AppContext }) => Promise<PayInvoiceResponse>
PayInvoice?: (req: PayInvoice_Input & {ctx: UserContext }) => Promise<PayInvoiceResponse>
RemoveAuthorizedDebit?: (req: RemoveAuthorizedDebit_Input & {ctx: UserContext }) => Promise<void>
RequestNPubLinkingToken?: (req: RequestNPubLinkingToken_Input & {ctx: AppContext }) => Promise<RequestNPubLinkingTokenResponse>
ResetNPubLinkingToken?: (req: ResetNPubLinkingToken_Input & {ctx: AppContext }) => Promise<RequestNPubLinkingTokenResponse>
SendAppUserToAppPayment?: (req: SendAppUserToAppPayment_Input & {ctx: AppContext }) => Promise<void>
@ -287,6 +299,14 @@ export const enumCheckAddressType = (e?: AddressType): boolean => {
for (const v in AddressType) if (e === v) return true
return false
}
export enum AuthorizedDebitType {
KEY = 'KEY',
NPUB = 'NPUB',
}
export const enumCheckAuthorizedDebitType = (e?: AuthorizedDebitType): boolean => {
for (const v in AuthorizedDebitType) if (e === v) return true
return false
}
export enum UserOperationType {
INCOMING_INVOICE = 'INCOMING_INVOICE',
INCOMING_TX = 'INCOMING_TX',
@ -668,6 +688,57 @@ export const AuthAppRequestValidate = (o?: AuthAppRequest, opts: AuthAppRequestO
return null
}
export type AuthorizedDebit = {
debit_id: string
debit_type: AuthorizedDebitType
key: string
}
export const AuthorizedDebitOptionalFields: [] = []
export type AuthorizedDebitOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
debit_id_CustomCheck?: (v: string) => boolean
debit_type_CustomCheck?: (v: AuthorizedDebitType) => boolean
key_CustomCheck?: (v: string) => boolean
}
export const AuthorizedDebitValidate = (o?: AuthorizedDebit, opts: AuthorizedDebitOptions = {}, path: string = 'AuthorizedDebit::root.'): Error | null => {
if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message')
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
if (typeof o.debit_id !== 'string') return new Error(`${path}.debit_id: is not a string`)
if (opts.debit_id_CustomCheck && !opts.debit_id_CustomCheck(o.debit_id)) return new Error(`${path}.debit_id: custom check failed`)
if (!enumCheckAuthorizedDebitType(o.debit_type)) return new Error(`${path}.debit_type: is not a valid AuthorizedDebitType`)
if (opts.debit_type_CustomCheck && !opts.debit_type_CustomCheck(o.debit_type)) return new Error(`${path}.debit_type: custom check failed`)
if (typeof o.key !== 'string') return new Error(`${path}.key: is not a string`)
if (opts.key_CustomCheck && !opts.key_CustomCheck(o.key)) return new Error(`${path}.key: custom check failed`)
return null
}
export type AuthorizedDebits = {
debits: AuthorizedDebit[]
}
export const AuthorizedDebitsOptionalFields: [] = []
export type AuthorizedDebitsOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
debits_ItemOptions?: AuthorizedDebitOptions
debits_CustomCheck?: (v: AuthorizedDebit[]) => boolean
}
export const AuthorizedDebitsValidate = (o?: AuthorizedDebits, opts: AuthorizedDebitsOptions = {}, path: string = 'AuthorizedDebits::root.'): Error | null => {
if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message')
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
if (!Array.isArray(o.debits)) return new Error(`${path}.debits: is not an array`)
for (let index = 0; index < o.debits.length; index++) {
const debitsErr = AuthorizedDebitValidate(o.debits[index], opts.debits_ItemOptions, `${path}.debits[${index}]`)
if (debitsErr !== null) return debitsErr
}
if (opts.debits_CustomCheck && !opts.debits_CustomCheck(o.debits)) return new Error(`${path}.debits: custom check failed`)
return null
}
export type BanUserRequest = {
user_id: string
}
@ -830,6 +901,25 @@ export const CreateOneTimeInviteLinkResponseValidate = (o?: CreateOneTimeInviteL
return null
}
export type DebitAuthorization = {
authorize_npub?: string
}
export type DebitAuthorizationOptionalField = 'authorize_npub'
export const DebitAuthorizationOptionalFields: DebitAuthorizationOptionalField[] = ['authorize_npub']
export type DebitAuthorizationOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: DebitAuthorizationOptionalField[]
authorize_npub_CustomCheck?: (v?: string) => boolean
}
export const DebitAuthorizationValidate = (o?: DebitAuthorization, opts: DebitAuthorizationOptions = {}, path: string = 'DebitAuthorization::root.'): Error | null => {
if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message')
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
if ((o.authorize_npub || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('authorize_npub')) && typeof o.authorize_npub !== 'string') return new Error(`${path}.authorize_npub: is not a string`)
if (opts.authorize_npub_CustomCheck && !opts.authorize_npub_CustomCheck(o.authorize_npub)) return new Error(`${path}.authorize_npub: custom check failed`)
return null
}
export type DecodeInvoiceRequest = {
invoice: string
}
@ -2028,6 +2118,24 @@ export const RelaysMigrationValidate = (o?: RelaysMigration, opts: RelaysMigrati
return null
}
export type RemoveAuthorizedDebitRequest = {
debit_id: string
}
export const RemoveAuthorizedDebitRequestOptionalFields: [] = []
export type RemoveAuthorizedDebitRequestOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
debit_id_CustomCheck?: (v: string) => boolean
}
export const RemoveAuthorizedDebitRequestValidate = (o?: RemoveAuthorizedDebitRequest, opts: RemoveAuthorizedDebitRequestOptions = {}, path: string = 'RemoveAuthorizedDebitRequest::root.'): Error | null => {
if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message')
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
if (typeof o.debit_id !== 'string') return new Error(`${path}.debit_id: is not a string`)
if (opts.debit_id_CustomCheck && !opts.debit_id_CustomCheck(o.debit_id)) return new Error(`${path}.debit_id: custom check failed`)
return null
}
export type RequestNPubLinkingTokenRequest = {
user_identifier: string
}