Compare commits
15 Commits
fc2bec6246
...
feature/no
| Author | SHA1 | Date | |
|---|---|---|---|
|
011386fb8d
|
|||
|
4d77f5d38c
|
|||
|
64de4deddd
|
|||
|
8f7994d82e
|
|||
|
a7d0e71ab6
|
|||
|
27d9f73c61
|
|||
|
ed3de8b16f
|
|||
|
d7b4c67953
|
|||
| 7489d4a32f | |||
|
ac77e5b7c1
|
|||
|
e544c28105
|
|||
|
4909dac5c2
|
|||
| 3cf4348695 | |||
|
af3da0a26c
|
|||
|
2d32320c7d
|
@@ -25,7 +25,6 @@ class Admin::SettingsController < Admin::BaseController
|
||||
end
|
||||
|
||||
changed_keys.each do |key|
|
||||
|
||||
Setting.send("#{key}=", clean_param(key))
|
||||
end
|
||||
end
|
||||
@@ -42,7 +41,7 @@ class Admin::SettingsController < Admin::BaseController
|
||||
|
||||
def clean_param(key)
|
||||
if Setting.get_field(key)[:type] == :string
|
||||
setting_params[key].strip!
|
||||
setting_params[key].strip
|
||||
else
|
||||
setting_params[key]
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class LnurlpayController < ApplicationController
|
||||
before_action :check_service_available
|
||||
before_action :find_user
|
||||
before_action :set_cors_access_control_headers, only: [:invoice]
|
||||
before_action :set_cors_access_control_headers
|
||||
|
||||
MIN_SATS = 10
|
||||
MAX_SATS = 1_000_000
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
class WebfingerController < ApplicationController
|
||||
class WebfingerController < WellKnownController
|
||||
before_action :allow_cross_origin_requests, only: [:show]
|
||||
|
||||
layout false
|
||||
|
||||
def show
|
||||
resource = params[:resource]
|
||||
|
||||
@@ -76,7 +74,7 @@ class WebfingerController < ApplicationController
|
||||
end
|
||||
|
||||
def remotestorage_link
|
||||
auth_url = new_rs_oauth_url(@username)
|
||||
auth_url = new_rs_oauth_url(@username, host: Setting.accounts_domain)
|
||||
storage_url = "#{Setting.rs_storage_url}/#{@username}"
|
||||
|
||||
{
|
||||
@@ -91,10 +89,4 @@ class WebfingerController < ApplicationController
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def allow_cross_origin_requests
|
||||
return unless Rails.env.development?
|
||||
headers['Access-Control-Allow-Origin'] = "*"
|
||||
headers['Access-Control-Allow-Methods'] = "GET"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
class WellKnownController < ApplicationController
|
||||
before_action :require_nostr_enabled, only: [ :nostr ]
|
||||
before_action :allow_cross_origin_requests, only: [ :nostr ]
|
||||
|
||||
layout false
|
||||
|
||||
def nostr
|
||||
http_status :unprocessable_entity and return if params[:name].blank?
|
||||
@@ -7,8 +10,14 @@ class WellKnownController < ApplicationController
|
||||
relay_url = Setting.nostr_relay_url.presence
|
||||
|
||||
if params[:name] == "_"
|
||||
# pubkey for the primary domain without a username (e.g. kosmos.org)
|
||||
res = { names: { "_": Setting.nostr_public_key } }
|
||||
if domain == Setting.primary_domain
|
||||
# pubkey for the primary domain without a username (e.g. kosmos.org)
|
||||
res = { names: { "_": Setting.nostr_public_key_primary_domain.presence || Setting.nostr_public_key } }
|
||||
else
|
||||
# pubkey for the akkounts domain without a username (e.g. accounts.kosmos.org)
|
||||
res = { names: { "_": Setting.nostr_public_key } }
|
||||
end
|
||||
|
||||
res[:relays] = { "_" => [ relay_url ] } if relay_url
|
||||
else
|
||||
@user = User.where(cn: params[:name], ou: domain).first
|
||||
@@ -30,4 +39,9 @@ class WellKnownController < ApplicationController
|
||||
def require_nostr_enabled
|
||||
http_status :not_found unless Setting.nostr_enabled?
|
||||
end
|
||||
|
||||
def allow_cross_origin_requests
|
||||
headers['Access-Control-Allow-Origin'] = "*"
|
||||
headers['Access-Control-Allow-Methods'] = "GET"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import { Nostrify } from "nostrify"
|
||||
|
||||
// Connects to data-controller="settings--nostr-pubkey"
|
||||
export default class extends Controller {
|
||||
static targets = [ "noExtension", "setPubkey", "pubkeyBech32Input" ]
|
||||
static targets = [
|
||||
"noExtension",
|
||||
"setPubkey", "pubkeyBech32Input",
|
||||
"relayList", "relayListStatus",
|
||||
"profileStatusNip05", "profileStatusLud16"
|
||||
]
|
||||
static values = {
|
||||
userAddress: String,
|
||||
pubkeyHex: String,
|
||||
@@ -15,6 +21,14 @@ export default class extends Controller {
|
||||
if (this.hasSetPubkeyTarget) {
|
||||
this.setPubkeyTarget.disabled = false
|
||||
}
|
||||
|
||||
if (this.pubkeyHexValue) {
|
||||
this.discoverUserOnNostr().then(() => {
|
||||
this.renderRelayStatus()
|
||||
this.renderProfileNip05Status()
|
||||
this.renderProfileLud16Status()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.noExtensionTarget.classList.remove("hidden")
|
||||
}
|
||||
@@ -49,8 +63,172 @@ export default class extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
async discoverUserOnNostr () {
|
||||
this.nip65Relays = await this.findUserRelays()
|
||||
this.profile = await this.findUserProfile()
|
||||
}
|
||||
|
||||
async findUserRelays () {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
const filters = [{ kinds: [10002], authors: [this.pubkeyHexValue], limit: 1 }]
|
||||
const messages = []
|
||||
|
||||
for await (const msg of this.discoveryPool.req(filters, { signal })) {
|
||||
if (msg[0] === 'EVENT') {
|
||||
if (!messages.find(m => m.id === msg[2].id)) {
|
||||
messages.push(msg[2])
|
||||
}
|
||||
}
|
||||
if (msg[0] === 'EOSE') { break }
|
||||
}
|
||||
|
||||
// Close the relay subscription
|
||||
controller.abort()
|
||||
if (messages.length === 0) { return messages }
|
||||
|
||||
const sortedMessages = messages.sort((a, b) => a.createdAt - b.createdAt)
|
||||
const newestMessage = messages[messages.length - 1]
|
||||
|
||||
return newestMessage.tags.filter(t => t[0] === 'r')
|
||||
.map(t => { return { url: t[1], marker: t[2] } })
|
||||
}
|
||||
|
||||
async findUserProfile () {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
const filters = [{ kinds: [0], authors: [this.pubkeyHexValue], limit: 1 }]
|
||||
const messages = []
|
||||
|
||||
for await (const msg of this.discoveryPool.req(filters, { signal })) {
|
||||
if (msg[0] === 'EVENT') {
|
||||
if (!messages.find(m => m.id === msg[2].id)) {
|
||||
messages.push(msg[2])
|
||||
}
|
||||
}
|
||||
if (msg[0] === 'EOSE') { break }
|
||||
}
|
||||
|
||||
// Close the relay subscription
|
||||
controller.abort()
|
||||
if (messages.length === 0) { return null }
|
||||
|
||||
const sortedMessages = messages.sort((a, b) => a.createdAt - b.createdAt)
|
||||
const newestMessage = messages[messages.length - 1]
|
||||
|
||||
return JSON.parse(newestMessage.content)
|
||||
}
|
||||
|
||||
renderRelayStatus () {
|
||||
let showStatus
|
||||
|
||||
if (this.nip65Relays.length > 0) {
|
||||
if (this.relaysContainAccountsRelay) {
|
||||
showStatus = 'green'
|
||||
} else {
|
||||
showStatus = 'orange'
|
||||
}
|
||||
} else {
|
||||
showStatus = 'red'
|
||||
}
|
||||
// showStatus = 'red'
|
||||
|
||||
this.relayListStatusTarget
|
||||
.querySelector(`.status-${showStatus}`)
|
||||
.classList.remove("hidden")
|
||||
}
|
||||
|
||||
renderProfileNip05Status () {
|
||||
let showStatus
|
||||
|
||||
if (this.profile?.nip05) {
|
||||
if (this.profile.nip05 === this.userAddressValue) {
|
||||
showStatus = 'green'
|
||||
} else {
|
||||
showStatus = 'red'
|
||||
}
|
||||
} else {
|
||||
showStatus = 'orange'
|
||||
}
|
||||
|
||||
this.profileStatusNip05Target
|
||||
.querySelector(`.status-${showStatus}`)
|
||||
.classList.remove("hidden")
|
||||
}
|
||||
|
||||
renderProfileLud16Status () {
|
||||
let showStatus
|
||||
|
||||
if (this.profile?.lud16) {
|
||||
if (this.profile.lud16 === this.userAddressValue) {
|
||||
showStatus = 'green'
|
||||
} else {
|
||||
showStatus = 'red'
|
||||
}
|
||||
} else {
|
||||
showStatus = 'orange'
|
||||
}
|
||||
|
||||
this.profileStatusLud16Target
|
||||
.querySelector(`.status-${showStatus}`)
|
||||
.classList.remove("hidden")
|
||||
}
|
||||
|
||||
// renderRelayList (relays) {
|
||||
// const html = relays.map(relay => `
|
||||
// <li class="flex items-center justify-between p-2 border-b">
|
||||
// <span>${relay.url}</span>
|
||||
// <button
|
||||
// data-action="click->list#handleItemClick"
|
||||
// data-item="${relay.url}"
|
||||
// class="bg-blue-500 text-white px-3 py-1 rounded">
|
||||
// Action
|
||||
// </button>
|
||||
// </li>
|
||||
// `).join("")
|
||||
//
|
||||
// this.relayListTarget.innerHTML = html
|
||||
// }
|
||||
|
||||
get csrfToken () {
|
||||
const element = document.head.querySelector('meta[name="csrf-token"]')
|
||||
return element.getAttribute("content")
|
||||
}
|
||||
|
||||
// Used to find a user's profile and relays
|
||||
get discoveryRelays () {
|
||||
return [
|
||||
'ws://localhost:4777',
|
||||
'wss://nostr.kosmos.org',
|
||||
'wss://purplepag.es',
|
||||
// 'wss://relay.nostr.band',
|
||||
// 'wss://njump.me',
|
||||
// 'wss://relay.damus.io',
|
||||
// 'wss://nos.lol',
|
||||
// 'wss://eden.nostr.land',
|
||||
// 'wss://relay.snort.social',
|
||||
// 'wss://nostr.wine',
|
||||
// 'wss://relay.primal.net',
|
||||
// 'wss://nostr.bitcoiner.social',
|
||||
]
|
||||
}
|
||||
|
||||
get discoveryPool () {
|
||||
if (!this._discoveryPool) {
|
||||
this._discoveryPool = new Nostrify.NPool({
|
||||
open: (url) => new Nostrify.NRelay1(url),
|
||||
reqRouter: async (filters) => new Map(
|
||||
this.discoveryRelays.map(relayUrl => [ relayUrl, filters ])
|
||||
),
|
||||
eventRouter: async (event) => [],
|
||||
})
|
||||
}
|
||||
|
||||
return this._discoveryPool
|
||||
}
|
||||
|
||||
get relaysContainAccountsRelay () {
|
||||
// TODO use URL from view/settings
|
||||
return !!this.nip65Relays.find(r => r.url.match('wss://nostr.kosmos.org'))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ module Settings
|
||||
field :nostr_public_key, type: :string,
|
||||
default: ENV["NOSTR_PUBLIC_KEY"].presence
|
||||
|
||||
field :nostr_public_key_primary_domain, type: :string,
|
||||
default: ENV["NOSTR_PUBLIC_KEY_PRIMARY_DOMAIN"].presence
|
||||
|
||||
field :nostr_relay_url, type: :string,
|
||||
default: ENV["NOSTR_RELAY_URL"].presence
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
<% Setting.available_services.each do |option| %>
|
||||
<div class="md:inline-block">
|
||||
<%= f.check_box :default_services,
|
||||
{ multiple: true, checked: Setting.default_services.include?(option) },
|
||||
{ multiple: true, checked: Setting.default_services.include?(option),
|
||||
class: "h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-600 mr-0.5" },
|
||||
option, nil %>
|
||||
<%= f.label "default_services_#{option.parameterize}", service_human_name(option) %>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
title: "Public key",
|
||||
description: "The corresponding public key of the accounts service"
|
||||
) %>
|
||||
<%= render FormElements::FieldsetResettableSettingComponent.new(
|
||||
key: :nostr_public_key_primary_domain,
|
||||
title: "Public key for primary domain (NIP-05)",
|
||||
description: "(optional) A different pubkey to announce for the _@#{Setting.primary_domain} Nostr address"
|
||||
) %>
|
||||
<%= render FormElements::FieldsetResettableSettingComponent.new(
|
||||
key: :nostr_relay_url,
|
||||
title: "Relay URL",
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
<td>XMPP (ejabberd)</td>
|
||||
<td>
|
||||
<%= render FormElements::ToggleComponent.new(
|
||||
enabled: @services_enabled.include?("xmpp"),
|
||||
enabled: @services_enabled.include?("ejabberd"),
|
||||
input_enabled: false
|
||||
) %>
|
||||
</td>
|
||||
|
||||
@@ -1,46 +1,32 @@
|
||||
<section>
|
||||
<h3>Nostr</h3>
|
||||
<h4 class="mb-0">Public Key</h4>
|
||||
<div data-controller="settings--nostr-pubkey"
|
||||
data-settings--nostr-pubkey-user-address-value="<%= current_user.address %>"
|
||||
data-settings--nostr-pubkey-site-value="<%= Setting.accounts_domain %>"
|
||||
data-settings--nostr-pubkey-shared-secret-value="<%= session[:shared_secret] %>"
|
||||
data-settings--nostr-pubkey-pubkey-hex-value="<%= current_user.nostr_pubkey %>">
|
||||
|
||||
<p class="<%= current_user.nostr_pubkey.present? ? '' : 'hidden' %> mt-2 flex gap-1">
|
||||
<div data-controller="settings--nostr-pubkey"
|
||||
data-settings--nostr-pubkey-user-address-value="<%= current_user.address %>"
|
||||
data-settings--nostr-pubkey-site-value="<%= Setting.accounts_domain %>"
|
||||
data-settings--nostr-pubkey-shared-secret-value="<%= session[:shared_secret] %>"
|
||||
data-settings--nostr-pubkey-pubkey-hex-value="<%= current_user.nostr_pubkey %>">
|
||||
<section>
|
||||
<h3>Nostr</h3>
|
||||
<h4 class="mb-0">
|
||||
Public Key
|
||||
</h4>
|
||||
<p class="<%= current_user.nostr_pubkey.present? ? '' : 'hidden' %> mt-2 flex gap-x-1">
|
||||
<input type="text" value="<%= current_user.nostr_pubkey_bech32 %>" disabled
|
||||
data-settings--nostr-pubkey-target="pubkeyBech32Input"
|
||||
name="nostr_public_key" class="relative grow" />
|
||||
name="nostr_public_key" class="w-full" />
|
||||
<%= link_to nostr_pubkey_settings_path,
|
||||
class: 'btn-md btn-outline text-red-700 relative shrink-0',
|
||||
class: 'btn-md btn-outline relative grow-0 shrink-0 text-red-700',
|
||||
data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' } do %>
|
||||
Remove
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<% if current_user.nostr_pubkey.present? %>
|
||||
<div class="rounded-md bg-blue-50 p-4">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="h-5 w-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3 flex-1">
|
||||
<p class="text-sm text-blue-800">
|
||||
Your user address <strong><%= current_user.address %></strong> is
|
||||
also a Nostr address now. Use your favorite Nostr app, or for
|
||||
example <a href="http://metadata.nostr.com" target="_blank"
|
||||
class="underline">metadata.nostr.com</a>, to add this
|
||||
<strong>NIP-05</strong> address to your public profile.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div> -->
|
||||
<!-- Pubkey present -->
|
||||
<!-- </div> -->
|
||||
<% else %>
|
||||
<p class="my-4">
|
||||
If you use any apps on the Nostr network, you can verify your public key
|
||||
with us in order to enable Nostr-specific features for your account.
|
||||
Verify your Nostr public key with us in order to enable Nostr-specific
|
||||
features for your account.
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
@@ -58,8 +44,8 @@
|
||||
</h3>
|
||||
<div class="mt-2 mb-0 text-sm text-blue-800">
|
||||
<p>
|
||||
We recommend Alby, which you can also use for your Lightning
|
||||
Wallet.
|
||||
We recommend Alby, which you can also use a wallet for your
|
||||
Lightning account.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
@@ -86,5 +72,113 @@
|
||||
</button>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<% if current_user.nostr_pubkey.present? %>
|
||||
<section>
|
||||
<h3>Profile</h3>
|
||||
<div data-settings--nostr-pubkey-target="profileStatus" class="mb-4">
|
||||
<p class="status-green hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-emerald-500 %>">
|
||||
<%= render "icons/check-circle" %>
|
||||
</span>
|
||||
<span>
|
||||
You already have a profile for your public key
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-orange hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
<strong><%= current_user.address %></strong> is not set as your Nostr address
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div data-settings--nostr-pubkey-target="profileStatusNip05" class="mb-4">
|
||||
<p class="status-green hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-emerald-500 %>">
|
||||
<%= render "icons/check-circle" %>
|
||||
</span>
|
||||
<span>
|
||||
<strong><%= current_user.address %></strong> is set as your Nostr address
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-orange hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
<strong><%= current_user.address %></strong> is not set as your Nostr address
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-red hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
Your profile's Nostr address is not set to <strong><%= current_user.address %></strong> yet
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div data-settings--nostr-pubkey-target="profileStatusLud16">
|
||||
<p class="status-green hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-emerald-500 %>">
|
||||
<%= render "icons/check-circle" %>
|
||||
</span>
|
||||
<span>
|
||||
<strong><%= current_user.address %></strong> is set as your Lightning address
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-orange hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
<strong><%= current_user.address %></strong> is not set as your Lightning address yet
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-red hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
Your profile's Lightning address is not set to <strong><%= current_user.address %></strong> yet
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Relays</h3>
|
||||
<div data-settings--nostr-pubkey-target="relayListStatus">
|
||||
<p class="status-green hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-emerald-500 %>">
|
||||
<%= render "icons/check-circle" %>
|
||||
</span>
|
||||
<span>
|
||||
You have a relay list, and the Kosmos relay is part of it
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-orange hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
The Kosmos relay is missing from your relay list
|
||||
</span>
|
||||
</p>
|
||||
<p class="status-red hidden flex gap-x-4 items-center">
|
||||
<span class="inline-block h-6 w-6 grow-0 text-amber-500 %>">
|
||||
<%= render "icons/alert-octagon" %>
|
||||
</span>
|
||||
<span>
|
||||
We could not find a relay list for your public key
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<ul data-settings--nostr-pubkey-target="relayList">
|
||||
</ul>
|
||||
</section>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -6,3 +6,4 @@ pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
|
||||
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
|
||||
pin_all_from "app/javascript/controllers", under: "controllers"
|
||||
pin "tailwindcss-stimulus-components" # @4.0.3
|
||||
pin "nostrify"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"postcss-preset-env": "^7.8.3",
|
||||
"tailwindcss": "^3.2.4"
|
||||
},
|
||||
"version": "0.9.0",
|
||||
"version": "0.10.0",
|
||||
"scripts": {
|
||||
"build:css:tailwind": "tailwindcss --postcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css",
|
||||
"build:css": "yarn run build:css:tailwind"
|
||||
|
||||
@@ -92,7 +92,13 @@ RSpec.describe "WebFinger", type: :request do
|
||||
expect(rs_link["href"]).to eql("#{Setting.rs_storage_url}/tony")
|
||||
|
||||
oauth_url = rs_link["properties"]["http://tools.ietf.org/html/rfc6749#section-4.2"]
|
||||
expect(oauth_url).to eql("http://www.example.com/rs/oauth/tony")
|
||||
expect(oauth_url).to eql("http://accounts.kosmos.org/rs/oauth/tony")
|
||||
end
|
||||
|
||||
it "returns CORS headers" do
|
||||
get "/.well-known/nostr.json?name=bobdylan"
|
||||
expect(response.headers['Access-Control-Allow-Origin']).to eq("*")
|
||||
expect(response.headers['Access-Control-Allow-Methods']).to eq('GET')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -46,6 +46,12 @@ RSpec.describe "Well-known URLs", type: :request do
|
||||
expect(res["names"]["bobdylan"]).to eq(user.nostr_pubkey)
|
||||
end
|
||||
|
||||
it "returns CORS headers" do
|
||||
get "/.well-known/nostr.json?name=bobdylan"
|
||||
expect(response.headers['Access-Control-Allow-Origin']).to eq("*")
|
||||
expect(response.headers['Access-Control-Allow-Methods']).to eq('GET')
|
||||
end
|
||||
|
||||
context "without relay configured" do
|
||||
before do
|
||||
Setting.nostr_relay_url = ""
|
||||
@@ -73,10 +79,36 @@ RSpec.describe "Well-known URLs", type: :request do
|
||||
end
|
||||
|
||||
describe "placeholder username for domain's own pubkey" do
|
||||
it "returns the configured nostr pubkey" do
|
||||
get "/.well-known/nostr.json?name=_"
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["names"]["_"]).to eq(Setting.nostr_public_key)
|
||||
describe "for primary domain" do
|
||||
context "no different pubkey configured for primary domain" do
|
||||
it "returns the akkounts nostr pubkey" do
|
||||
get "/.well-known/nostr.json?name=_"
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["names"]["_"]).to eq("bdd76ce2934b2f591f9fad2ebe9da18f20d2921de527494ba00eeaa0a0efadcf")
|
||||
end
|
||||
end
|
||||
|
||||
context "different pubkey configured for primary domain" do
|
||||
before do
|
||||
Setting.nostr_public_key_primary_domain = "b3e8f62fbe41217ffc0aa1e178d297339932d8ba4f46d9c7df3b61575e78fecc"
|
||||
end
|
||||
|
||||
it "returns the primary domain's nostr pubkey" do
|
||||
get "/.well-known/nostr.json?name=_"
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["names"]["_"]).to eq("b3e8f62fbe41217ffc0aa1e178d297339932d8ba4f46d9c7df3b61575e78fecc")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "for akkounts domain" do
|
||||
it "returns the configured nostr pubkey" do
|
||||
headers = { "X-Forwarded-Host" => "accounts.kosmos.org" }
|
||||
get "/.well-known/nostr.json?name=_"
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["names"]["_"]).to eq("bdd76ce2934b2f591f9fad2ebe9da18f20d2921de527494ba00eeaa0a0efadcf")
|
||||
end
|
||||
end
|
||||
|
||||
context "with relay configured" do
|
||||
|
||||
11690
vendor/javascript/nostrify.js
vendored
Normal file
11690
vendor/javascript/nostrify.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
vendor/javascript/nostrify.js.map
vendored
Normal file
1
vendor/javascript/nostrify.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user