~sircmpwn/hire.sr.ht

5f941c9591bb2a7adb1fb584d5f32a79784f6c85 — Willow Barraco 9 months ago 124a866
Add contact_url to profile, to let the hacker use whathever they want

Fixes: https://todo.sr.ht/~renato/hire.sr.ht/24
Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
M api/graph/model/profile.go => api/graph/model/profile.go +2 -0
@@ 28,6 28,7 @@ type Profile struct {
	Created     time.Time `json:"created"`
	Updated     time.Time `json:"updated"`
	DisplayName string    `json:"displayName"`
	ContactURL  string    `json:"contactURL"`
	Snippet     string    `json:"snippet"`
	Bio         string    `json:"bio"`
	Image       *string   `json:"image"`


@@ 74,6 75,7 @@ func (p *Profile) Fields() *database.ModelFields {
			{"created", "created", &p.Created},
			{"updated", "updated", &p.Updated},
			{"display_name", "displayName", &p.DisplayName},
			{"contact_url", "contactURL", &p.ContactURL},
			{"snippet", "snippet", &p.Snippet},
			{"bio", "bio", &p.Bio},
			{"image", "image", &p.Image},

M api/graph/schema.graphqls => api/graph/schema.graphqls +2 -0
@@ 87,6 87,7 @@ type Profile {
  updated: Time!

  displayName: String!
  contactURL: String!
  snippet: String!
  bio: String!
  image: URL


@@ 204,6 205,7 @@ price points.
"""
input ProfileInput {
  displayName: String
  contactURL: String
  snippet: String
  bio: String
  image: Upload

M api/graph/schema.resolvers.go => api/graph/schema.resolvers.go +12 -0
@@ 55,6 55,12 @@ func (r *mutationResolver) CreateProfile(ctx context.Context, input map[string]i
			WithField(`displayName`)
		profile.DisplayName = name
	})
	validation.OptionalString(`contactURL`, func(name string) {
		validation.Expect(len(name) <= 256,
			"Contact url must be less than 257 characters").
			WithField(`contactURL`)
		profile.DisplayName = name
	})
	validation.OptionalString(`snippet`, func(snippet string) {
		validation.Expect(len(snippet) <= 1024,
			"Snippet must be less than 1025 characters").


@@ 222,6 228,12 @@ func (r *mutationResolver) UpdateProfile(ctx context.Context, id int, input map[
			WithField(`displayName`)
		update = update.Set(`display_name`, name)
	})
	validation.OptionalString(`contactURL`, func(name string) {
		validation.Expect(len(name) <= 256,
			"Contact URL must be less than 257 characters").
			WithField(`contactURL`)
		update = update.Set(`contact_url`, name)
	})
	validation.OptionalString(`snippet`, func(snippet string) {
		validation.Expect(len(snippet) <= 1024,
			"Snippet must be less than 1025 characters").

M hiresrht/blueprints/profile.py => hiresrht/blueprints/profile.py +5 -0
@@ 52,6 52,7 @@ def create_POST():
def _create_update_profile(profile_id=None):
    valid = Validation(request)
    valid.require("display_name", friendly_name="Display name")
    valid.require("contact_url", friendly_name="Contact URL")
    valid.require("snippet", friendly_name="Short blurb")
    valid.require("bio", friendly_name="Longer description")
    valid.require("currency", friendly_name="Preferred currency")


@@ 125,6 126,7 @@ def _build_profile(valid):
    profile = {
        key: rewrite(valid.source[key]) for key in [
            "display_name",
            "contact_url",
            "snippet",
            "bio",
        ] if valid.source.get(key) is not None


@@ 133,6 135,9 @@ def _build_profile(valid):
    profile["displayName"] = valid.source.get("display_name")
    profile.pop("display_name")

    profile["contactURL"] = valid.source.get("contact_url")
    profile.pop("contact_url")

    profile["listed"] = valid.source.get("listed", "") == "on"
    profile["fixed"] = valid.source.get("fixed", "") == "on"
    profile["negotiable"] = valid.source.get("negotiable", "") == "on"

M hiresrht/blueprints/services.py => hiresrht/blueprints/services.py +3 -0
@@ 12,6 12,7 @@ def search_profiles(page, filter, search_user):
                created
                updated
                displayName
                contactURL
                snippet
                bio
                tags


@@ 48,6 49,7 @@ def update_profile(username, profile_id, valid, input, avatar):
    vars = {
        "input": {
            "displayName": input.get("displayName"),
            "contactURL": input.get("contactURL"),
            "snippet": input.get("snippet"),
            "bio": input.get("bio"),
            "tags": input.get("tags"),


@@ 146,6 148,7 @@ def get_profile(username):
                    created
                    updated
                    displayName
                    contactURL
                    snippet
                    bio
                    tags

M hiresrht/templates/create_update.html => hiresrht/templates/create_update.html +16 -0
@@ 75,6 75,22 @@
          </small>
        </div>
        <div class="form-group">
          <label for="contact_url">Contact URL</label>
          <input
            class="form-control {{valid.cls("contact_url")}}"
            name="contact_url"
            id="contact_url"
            type="text"
            placeholder="mailto://contact@jane-doe.com"
            aria-describedby="contact_url_help"
            value="{{contactURL or ""}}"
            maxlength="256" />
          {{valid.summary("contact_url")}}
          <small id="contact_url_help" class="form-text text-muted">
            Your contact url. Prefix with mailto:// if you use your email address.
          </small>
        </div>
        <div class="form-group">
          <label for="snippet">Short blurb</label>
          <textarea
            class="form-control {{valid.cls("snippet")}}"

M hiresrht/templates/index.html => hiresrht/templates/index.html +1 -1
@@ 65,7 65,7 @@
              {% endif %}
            </div>
            <div class="col-md-3 centered">
              <a class="btn btn-primary btn-block">
              <a class="btn btn-primary btn-block" href="{{ contactURL }}">
                Contact {{display_name}} {{icon("caret-right")}}
              </a>
            </div>

M schema.sql => schema.sql +1 -0
@@ 72,6 72,7 @@ CREATE TABLE profile (
	user_id integer NOT NULL UNIQUE REFERENCES "user"(id) ON DELETE CASCADE,
	display_name text NOT NULL,
	snippet text NOT NULL,
	contact_url text NOT NULL,
	bio text NOT NULL,
	fts_vector tsvector NOT NULL,
	image text,