0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-22 17:30:29 +01:00

Merge branch 'main' into admin-acceptance-tests

Dieser Commit ist enthalten in:
jumagura 2022-12-19 11:51:41 -04:00
Commit 23fafeaf05
16 geänderte Dateien mit 95 neuen und 19 gelöschten Zeilen

7
SECURITY.md Normale Datei
Datei anzeigen

@ -0,0 +1,7 @@
# Security Policy
The security of Discourse plugins are premised on the security of [Discourse](https://github.com/discourse/discourse). Please first consider whether a security issue is best reported and handled by the Discourse team. You can view the Discourse security policy [here](https://github.com/discourse/discourse/security/policy).
## Reporting a Vulnerability
If you find a security vulnerability that is specific to this plugin, please report it to development@pavilion.tech. Security issues always take precedence over all other work. All commits specific to security are prefixed with SECURITY.

Datei anzeigen

@ -114,6 +114,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
:property, :property,
:preview_template, :preview_template,
:placeholder, :placeholder,
:can_create_tag,
prefill: mapped_params, prefill: mapped_params,
content: mapped_params, content: mapped_params,
condition: mapped_params, condition: mapped_params,

Datei anzeigen

@ -17,6 +17,7 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
:property, :property,
:content, :content,
:tag_groups, :tag_groups,
:can_create_tag,
:validations, :validations,
:max_length, :max_length,
:char_counter, :char_counter,
@ -98,6 +99,10 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
object.tag_groups object.tag_groups
end end
def can_create_tag
object.can_create_tag
end
def validations def validations
validations = {} validations = {}
object.validations&.each do |type, props| object.validations&.each do |type, props|

Datei anzeigen

@ -149,7 +149,7 @@ export default ComposerEditor.extend({
extraButtons(toolbar) { extraButtons(toolbar) {
const component = this; const component = this;
if (this.allowUpload && this.uploadIcon && !this.site.mobileView) { if (this.allowUpload && this.uploadIcon) {
toolbar.addButton({ toolbar.addButton({
id: "upload", id: "upload",
group: "insertions", group: "insertions",

Datei anzeigen

@ -5,11 +5,7 @@ import { scheduleOnce } from "@ember/runloop";
import Component from "@ember/component"; import Component from "@ember/component";
import I18n from "I18n"; import I18n from "I18n";
const excludedUserProperties = [ const excludedUserProperties = ["profile_background", "card_background"];
"avatar",
"profile_background",
"card_background",
];
export default Component.extend({ export default Component.extend({
classNames: "wizard-text-editor", classNames: "wizard-text-editor",
@ -52,12 +48,12 @@ export default Component.extend({
@discourseComputed("wizardFields") @discourseComputed("wizardFields")
wizardFieldList(wizardFields) { wizardFieldList(wizardFields) {
return wizardFields.map((f) => ` w{${f.id}}`); return (wizardFields || []).map((f) => ` w{${f.id}}`);
}, },
@discourseComputed("wizardActions") @discourseComputed("wizardActions")
wizardActionList(wizardActions) { wizardActionList(wizardActions) {
return wizardActions.map((a) => ` w{${a.id}}`); return (wizardActions || []).map((a) => ` w{${a.id}}`);
}, },
actions: { actions: {

Datei anzeigen

@ -36,7 +36,8 @@ export default Controller.extend({
@discourseComputed("wizard.id") @discourseComputed("wizard.id")
wizardUrl(wizardId) { wizardUrl(wizardId) {
return window.location.origin + "/w/" + dasherize(wizardId); let baseUrl = window.location.href.split("/admin");
return baseUrl[0] + "/w/" + dasherize(wizardId);
}, },
@discourseComputed("wizard.after_time_scheduled") @discourseComputed("wizard.after_time_scheduled")

Datei anzeigen

@ -5,4 +5,5 @@
everyTag=true everyTag=true
options=(hash options=(hash
maximum=field.limit maximum=field.limit
allowAny=field.can_create_tag
)}} )}}

Datei anzeigen

@ -222,6 +222,18 @@
}} }}
</div> </div>
</div> </div>
<div class="setting">
<div class="setting-label">
<label>{{i18n "admin.wizard.field.can_create_tag"}}</label>
</div>
<div class="setting-value">
{{input
type="checkbox"
checked=field.can_create_tag}}
</div>
</div>
{{/if}} {{/if}}
{{#wizard-subscription-container}} {{#wizard-subscription-container}}

Datei anzeigen

@ -16,7 +16,7 @@ en:
x_characters: x_characters:
one: "%{count} Character" one: "%{count} Character"
other: "%{count} Characters" other: "%{count} Characters"
quit: "Maybe Later" quit: "Exit"
done_custom: "Done" done_custom: "Done"
back: "Back" back: "Back"
next: "Next" next: "Next"
@ -277,6 +277,7 @@ en:
prefill: "Prefill" prefill: "Prefill"
content: "Content" content: "Content"
tag_groups: "Tag Groups" tag_groups: "Tag Groups"
can_create_tag: "Can Create Tag"
date_time_format: date_time_format:
label: "Format" label: "Format"
instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>" instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>"

Datei anzeigen

@ -20,9 +20,6 @@ pre-commit:
glob: "*.js" glob: "*.js"
include: "app/assets/javascripts|plugins/.+?/assets/javascripts" include: "app/assets/javascripts|plugins/.+?/assets/javascripts"
run: yarn eslint -f compact --quiet {staged_files} run: yarn eslint -f compact --quiet {staged_files}
i18n-lint:
glob: "**/{client,server}.en.yml"
run: bundle exec ruby script/i18n_lint.rb {staged_files}
lints: lints:
parallel: true parallel: true
@ -36,6 +33,3 @@ lints:
run: yarn prettier --list-different **/*.scss run: yarn prettier --list-different **/*.scss
eslint: eslint:
run: yarn eslint -f compact --quiet --ext .js . run: yarn eslint -f compact --quiet --ext .js .
i18n-lint:
glob: "**/{client,server}.en.yml"
run: bundle exec ruby script/i18n_lint.rb {all_files}

Datei anzeigen

@ -135,6 +135,10 @@ class CustomWizard::Builder
params[:limit] = field_template['limit'] params[:limit] = field_template['limit']
end end
if field_template['type'] === 'tag'
params[:can_create_tag] = standardise_boolean(field_template['can_create_tag'])
end
if field_template['type'] === 'category' if field_template['type'] === 'category'
params[:property] = field_template['property'] params[:property] = field_template['property']
end end

Datei anzeigen

@ -22,6 +22,7 @@ class CustomWizard::Field
:property, :property,
:content, :content,
:tag_groups, :tag_groups,
:can_create_tag,
:preview_template, :preview_template,
:placeholder :placeholder
@ -47,6 +48,7 @@ class CustomWizard::Field
@property = attrs[:property] @property = attrs[:property]
@content = attrs[:content] @content = attrs[:content]
@tag_groups = attrs[:tag_groups] @tag_groups = attrs[:tag_groups]
@can_create_tag = attrs[:can_create_tag]
@preview_template = attrs[:preview_template] @preview_template = attrs[:preview_template]
@placeholder = attrs[:placeholder] @placeholder = attrs[:placeholder]
end end
@ -113,7 +115,8 @@ class CustomWizard::Field
limit: nil, limit: nil,
prefill: nil, prefill: nil,
content: nil, content: nil,
tag_groups: nil tag_groups: nil,
can_create_tag: false
}, },
category: { category: {
limit: 1, limit: 1,

Datei anzeigen

@ -211,6 +211,8 @@ class CustomWizard::Mapper
user.send(value) user.send(value)
elsif USER_OPTION_FIELDS.include?(value) elsif USER_OPTION_FIELDS.include?(value)
user.user_option.send(value) user.user_option.send(value)
elsif value.include?('avatar')
get_avatar_url(value)
else else
nil nil
end end
@ -269,4 +271,15 @@ class CustomWizard::Mapper
def bool(value) def bool(value)
ActiveRecord::Type::Boolean.new.cast(value) ActiveRecord::Type::Boolean.new.cast(value)
end end
def get_avatar_url(value)
parts = value.split('.')
valid_sizes = Discourse.avatar_sizes.to_a
if value === 'avatar' || parts.size === 1 || valid_sizes.exclude?(parts.last.to_i)
user.small_avatar_url
else
user.avatar_template_url.gsub("{size}", parts.last)
end
end
end end

Datei anzeigen

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
# name: discourse-custom-wizard # name: discourse-custom-wizard
# about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more. # about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more.
# version: 2.0.7 # version: 2.1.3
# authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever # authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever
# url: https://github.com/paviliondev/discourse-custom-wizard # url: https://github.com/paviliondev/discourse-custom-wizard
# contact_emails: development@pavilion.tech # contact_emails: development@pavilion.tech

Datei anzeigen

@ -1,4 +1,4 @@
# frozen_string_literal: true # rubocop:disable Style/FrozenStringLiteralComment
describe CustomWizard::Mapper do describe CustomWizard::Mapper do
fab!(:user1) { fab!(:user1) {
@ -254,6 +254,36 @@ describe CustomWizard::Mapper do
user: user1 user: user1
).perform).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}") ).perform).to eq("Time: #{Time.now.strftime("%B %-d, %Y")}")
end end
it "avatar" do
expect(CustomWizard::Mapper.new(
inputs: inputs['interpolate_avatar'],
data: data,
user: user1
).perform).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
end
it "avatar with invalid size" do
avatar_inputs = inputs['interpolate_avatar'].dup
avatar_inputs[0]["output"] = "Avatar: ![avatar](u{avatar.345})"
expect(CustomWizard::Mapper.new(
inputs: avatar_inputs,
data: data,
user: user1
).perform).to eq("Avatar: ![avatar](#{user1.small_avatar_url})")
end
it "avatar with valid size" do
avatar_inputs = inputs['interpolate_avatar'].dup
avatar_inputs[0]["output"] = "Avatar: ![avatar](u{avatar.120})"
expect(CustomWizard::Mapper.new(
inputs: avatar_inputs,
data: data,
user: user1
).perform).to eq("Avatar: ![avatar](#{user1.avatar_template_url.gsub("{size}", "120")})")
end
end end
it "handles greater than pairs" do it "handles greater than pairs" do

Datei anzeigen

@ -89,6 +89,14 @@
"output": "Time: v{time}" "output": "Time: v{time}"
} }
], ],
"interpolate_avatar": [
{
"type": "assignment",
"output_type": "text",
"output_connector": "set",
"output": "Avatar: ![avatar](u{avatar})"
}
],
"validation": [ "validation": [
{ {
"type": "validation", "type": "validation",