mirror of
https://github.com/System-End/identity-vault.git
synced 2026-04-20 00:25:21 +00:00
* INITIAL SAML SUPPORT WOO YEA BABEY it works? * wawa * mwaow * b * WOAG * mph * bunch more stuff * new OAuth screen * add trust level to oauth apps * [community oauth] new scopes, validate only some community ones * bleh * my info first pass * sessions and 2fa * oauth authorizations/revoke * nuke sms * fix drift * remove hcid on ident#edit * attack our rack? * session fixation't * first pass at stepup auth * eye eighteen en * fix brand * think that does it for dev mode! * add promote to full user button * first crack at landing page * better sessions * better id edit * better verf * less css pass 1 * add phone no * better cssed? * securité * switch from slocks * HCA * touch last seen at * session fingerprinting * improved? * localize scopes * add proper oauth welcome * eepier tutorial * how long was that like that?! * common blankslate * better addresses? * [backend] fix reprovisioning and promotion * improve addresses * ICONS, BEAUTIFUL ICONS * primary sidebar * saml welcome? * new totp flow? * marginally better login sec * better print for backup codes! * MASSIVE LINT PASS * autocompletes * woops * new staging * actual login code txnl * no more legacy slack account linking * fake slack in staging * no account yet? * add samls for staging * fix slack_staging * lint * frickin' xmlsec * no validate keys ? * AUGH * ASGJHFGSDJFG * shoot me * aieeeee * SCHEIßE * no more attempt association on code * believe in prefers-color-scheme * fix verf icon * nuke vestigial aadhaar functionality thanks deployor! * fix xmlsec on gh ci * remove identity (#27) * move idcon flashes to locale * remove dead code impersonation logic h/t ian! * fix hx-confirm on delete address? * add missing dev app locale key * fix #28 * wait, i'm an idiot (#28) * THERE WE GO * add paper_trail to more stuff * red delete btn * more red delete btns * THE AUDIT LOGS UPDATE * yuge lint pass * Fix icons (#33) Some icons didn't have a fill nor a viewbox * weh * first pass at docs * memoize docs, fix 404 * [docs] add crappy erb support * support non-e+ flow * fix no devmode locale * DOCS DOCS DOCS * tldr dev doc * anti-clickjacking countdown (h/t @J-Meow) * weh * get rid of those, they do nothing for us * dependent destroy * find user via scim if ent * save nav channel ids * fix base onboarding scenario * only unique among the living * add SAML debug * simplify legacy_email * add UAT env * we ARE * add slack to uat * no entity id? * fix saml if logged out * fix scim assignment? * bring channels into config * darn it * try backoff on assign_to_workspace?? this feels problematic * do the scim docs lie? * that was dumb * Revert "do the scim docs lie?" This reverts commit 69310dbef9476f2103d7a8280966a7fdf732129b. * Revert "try backoff on assign_to_workspace?? this feels problematic" This reverts commit 7a5edd67aa3836df1f31d628566e9ea69589c269. * this some bull shit * internal tutorial by default * 18 point something * fixes: componentize login, no more viewcontext, parse sp-initiated saml better * one return to. * just send it * fix replay bug * fix URL in welcome docs page (#38) * simplify login/signup flow, s/faq/terms + privacy * no more H... we hardly knew you * first pass at reddening * red pt. 2 * she's red for an AMAZING reason * lint pass * fix tooled tips * another docs pass * initial pass at factorybotting docs * scope diffing for api docs! * wait we don't need a legend lol * add verf status to community apps * fricken lint * make current_user not nomethod * move are_we_enterprise_yet to a flipper flag * improve slack racing * allow not creating slack * factorybot in prod for api docs! * LOL, LMAO * properly set owner on oauthorizations * lint pass * bypass age on existing users * fix that... --------- Co-authored-by: Leo <leo@wilkin.xyz> Co-authored-by: Tom (Deployor) <129990841+deployor@users.noreply.github.com> Co-authored-by: DaInfLoop <github@dainfloop.is-a.dev>
150 lines
4.4 KiB
Ruby
150 lines
4.4 KiB
Ruby
class DocsController < ApplicationController
|
|
layout "docs"
|
|
skip_before_action :authenticate_identity!, only: [ :index, :show ]
|
|
|
|
before_action :set_doc_path, only: :show
|
|
before_action :load_all_docs, only: [ :index, :show ]
|
|
|
|
def index
|
|
first_doc = @all_docs.first
|
|
return render plain: "No documentation found" if first_doc.nil?
|
|
|
|
redirect_to doc_path(slug: first_doc[:slug])
|
|
end
|
|
|
|
def show
|
|
raise ActionController::RoutingError, "Documentation not found" unless File.exist?(@doc_file_path)
|
|
|
|
@doc = parse_doc_file(@doc_file_path, params[:slug])
|
|
render :show
|
|
rescue StandardError => e
|
|
raise if e.is_a?(ActionController::RoutingError)
|
|
|
|
Rails.logger.error("Error parsing frontmatter for #{params[:slug]}: #{e.message}")
|
|
@doc = {
|
|
slug: params[:slug],
|
|
title: "Error",
|
|
content: "<p>Error parsing documentation.</p>"
|
|
}
|
|
render :show
|
|
end
|
|
|
|
private
|
|
|
|
def set_doc_path
|
|
slug = params[:slug] || "index"
|
|
|
|
# Sanitize the slug to prevent directory traversal
|
|
if slug.include?("..") || slug.include?("/")
|
|
raise ActionController::RoutingError, "Invalid documentation path"
|
|
end
|
|
|
|
erb_path = Rails.root.join("app", "views", "docs", "#{slug}.md.erb")
|
|
md_path = Rails.root.join("app", "views", "docs", "#{slug}.md")
|
|
|
|
@doc_file_path = File.exist?(erb_path) ? erb_path : md_path
|
|
end
|
|
|
|
def load_all_docs
|
|
@all_docs ||= begin
|
|
docs_dir = Rails.root.join("app", "views", "docs")
|
|
return [] unless Dir.exist?(docs_dir)
|
|
|
|
Dir.glob(docs_dir.join("*.md{,.erb}")).map do |file_path|
|
|
parsed = parse_frontmatter(file_path)
|
|
next unless parsed
|
|
|
|
slug = File.basename(file_path, ".*")
|
|
slug = File.basename(slug, ".*") if file_path.end_with?(".md.erb")
|
|
|
|
{
|
|
slug: slug,
|
|
title: parsed["title"] || slug.titleize,
|
|
category: parsed["category"],
|
|
order: parsed["order"] || 999,
|
|
hidden: parsed["hidden"] || false
|
|
}
|
|
rescue => e
|
|
Rails.logger.error("Error parsing doc #{file_path}: #{e.message}")
|
|
nil
|
|
end.compact.reject { |doc| doc[:hidden] }.sort_by { |doc| doc[:order] }
|
|
end
|
|
end
|
|
|
|
def parse_frontmatter(file_path)
|
|
cache_key = "doc_frontmatter:#{file_path}:#{File.mtime(file_path).to_i}"
|
|
Rails.cache.fetch(cache_key, expires_in: 1.hour) do
|
|
content = read_doc_content(file_path)
|
|
FrontMatterParser::Parser.new(:md).call(content)
|
|
end
|
|
end
|
|
|
|
def parse_doc_file(file_path, slug)
|
|
cache_key = "doc_content:#{file_path}:#{File.mtime(file_path).to_i}"
|
|
Rails.cache.fetch(cache_key, expires_in: 1.hour) do
|
|
content = File.read(file_path)
|
|
parsed = FrontMatterParser::Parser.new(:md).call(content)
|
|
|
|
# this is DISGUSTING, i'm sorry...
|
|
if file_path.to_s.end_with?(".erb")
|
|
erb_tags = []
|
|
content_with_placeholders = parsed.content.gsub(/<%=?.*?%>/m) do |match|
|
|
erb_tags << match
|
|
"ERB_PLACEHOLDER_#{erb_tags.length - 1}_PLACEHOLDER"
|
|
end
|
|
|
|
markdown_content = render_markdown(content_with_placeholders)
|
|
|
|
erb_tags.each_with_index do |erb_tag, index|
|
|
markdown_content = markdown_content.gsub("ERB_PLACEHOLDER_#{index}_PLACEHOLDER", erb_tag)
|
|
end
|
|
|
|
template = ERB.new(markdown_content)
|
|
final_content = template.result(view_context.instance_eval { binding })
|
|
else
|
|
final_content = render_markdown(parsed.content)
|
|
end
|
|
|
|
{
|
|
slug: slug,
|
|
title: parsed["title"] || "Untitled",
|
|
description: parsed["description"],
|
|
category: parsed["category"],
|
|
order: parsed["order"] || 999,
|
|
content: final_content.html_safe
|
|
}
|
|
end
|
|
end
|
|
|
|
def read_doc_content(file_path)
|
|
content = File.read(file_path)
|
|
if file_path.to_s.end_with?(".erb")
|
|
template = ERB.new(content)
|
|
template.result(view_context.instance_eval { binding })
|
|
else
|
|
content
|
|
end
|
|
end
|
|
|
|
def render_markdown(text)
|
|
renderer = Redcarpet::Render::HTML.new(
|
|
hard_wrap: true,
|
|
link_attributes: { target: "_blank", rel: "noopener noreferrer" }
|
|
)
|
|
|
|
markdown = Redcarpet::Markdown.new(
|
|
renderer,
|
|
autolink: false,
|
|
tables: true,
|
|
fenced_code_blocks: true,
|
|
strikethrough: true,
|
|
superscript: true,
|
|
highlight: true,
|
|
footnotes: true,
|
|
no_intra_emphasis: true,
|
|
disable_indented_code_blocks: true
|
|
)
|
|
|
|
markdown.render(text).html_safe
|
|
end
|
|
end
|