~netlandish/links

c3a4b57269354e58df827cd78d1f13eebe35620d — Peter Sanchez 9 months ago 9295c97
Adding index redirect for short service.

Implements: https://todo.code.netlandish.com/~netlandish/links/49
1 files changed, 91 insertions(+), 83 deletions(-)

M short/routes.go
M short/routes.go => short/routes.go +91 -83
@@ 580,89 580,6 @@ func NewService(eg *echo.Group) *Service {
	return service
}

type RedirectService struct {
	name string
	eg   *echo.Group
}

func (r *RedirectService) RegisterRoutes() {
	r.eg.GET("/:code", r.LinkShort).Name = r.RouteName("link_short")
}

func (r *RedirectService) LinkShort(c echo.Context) error {
	code := c.Param("code")
	if code == "" {
		return echo.NotFoundHandler(c)
	}
	type GraphQLResponse struct {
		LinkShort models.LinkShort `json:"getLinkShort"`
	}

	var result GraphQLResponse
	op := gqlclient.NewOperation(
		`query GetLinkShort($code: String!, $domain: Int) {
				getLinkShort(shortCode: $code, domainId: $domain) {
					id
					url
					orgId
				}
		}`)

	op.Var("code", code)
	domain := domain.ForContext(c.Request().Context())
	op.Var("domain", domain.ID)

	err := links.Execute(c.Request().Context(), op, &result)
	if err != nil {
		if graphError, ok := err.(*gqlclient.Error); ok {
			err = links.ParseInputErrors(c, graphError, gobwebs.Map{})
		}
		return err
	}

	linkShort := result.LinkShort
	// Append the query params passed in the url
	// to the redirect url params
	query := c.QueryParams()
	recURL, err := links.AppendQueryParams(linkShort.URL, query)
	if err != nil {
		return err
	}
	gctx := c.(*server.Context)
	srv := gctx.Server
	req := c.Request()
	srv.QueueTask("general", analytics.AddAnalyticsTask(
		srv,
		req,
		result.LinkShort.ID,
		analytics.LinkShortAnalyticsFilter,
	))

	opts := &database.FilterOptions{
		Filter: sq.Eq{"o.id": linkShort.OrgID},
		Limit:  1,
	}
	orgs, err := models.GetOrganizations(c.Request().Context(), opts)
	if err != nil {
		return err
	}
	if len(orgs) == 0 {
		return echo.NotFoundHandler(c)
	}

	org := orgs[0]
	if links.BillingEnabled(gctx.Server.Config) && org.IsRestricted(
		[]int{models.BillingStatusFree, models.BillingStatusOpenSource}) {
		gmap := gobwebs.Map{
			"url":     recURL,
			"hideNav": true,
		}
		return gctx.Render(http.StatusOK, "restriction_redirect.html", gmap)
	}

	return c.Redirect(http.StatusMovedPermanently, recURL)
}

func (s *Service) LinkShortQRCodeList(c echo.Context) error {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {


@@ 887,6 804,97 @@ func (s *Service) LinkShortQRCodeCreate(c echo.Context) error {
	return gctx.Render(http.StatusOK, "qrcode_detail.html", gmap)
}

type RedirectService struct {
	name string
	eg   *echo.Group
}

func (r *RedirectService) RegisterRoutes() {
	r.eg.GET("/:code", r.LinkShort).Name = r.RouteName("link_short")
	r.eg.GET("/", r.Index).Name = r.RouteName("link_short_index")
}

func (r *RedirectService) Index(c echo.Context) error {
	// No need to check for domain. A short domain will not be set to the
	// links service domain. And no default index for short so just redirect.
	linksURL := links.GetLinksDomainURL(c)
	return c.Redirect(http.StatusMovedPermanently, linksURL.String())
}

func (r *RedirectService) LinkShort(c echo.Context) error {
	code := c.Param("code")
	if code == "" {
		return echo.NotFoundHandler(c)
	}
	type GraphQLResponse struct {
		LinkShort models.LinkShort `json:"getLinkShort"`
	}

	var result GraphQLResponse
	op := gqlclient.NewOperation(
		`query GetLinkShort($code: String!, $domain: Int) {
				getLinkShort(shortCode: $code, domainId: $domain) {
					id
					url
					orgId
				}
		}`)

	op.Var("code", code)
	domain := domain.ForContext(c.Request().Context())
	op.Var("domain", domain.ID)

	err := links.Execute(c.Request().Context(), op, &result)
	if err != nil {
		if graphError, ok := err.(*gqlclient.Error); ok {
			err = links.ParseInputErrors(c, graphError, gobwebs.Map{})
		}
		return err
	}

	linkShort := result.LinkShort
	// Append the query params passed in the url
	// to the redirect url params
	query := c.QueryParams()
	recURL, err := links.AppendQueryParams(linkShort.URL, query)
	if err != nil {
		return err
	}
	gctx := c.(*server.Context)
	srv := gctx.Server
	req := c.Request()
	srv.QueueTask("general", analytics.AddAnalyticsTask(
		srv,
		req,
		result.LinkShort.ID,
		analytics.LinkShortAnalyticsFilter,
	))

	opts := &database.FilterOptions{
		Filter: sq.Eq{"o.id": linkShort.OrgID},
		Limit:  1,
	}
	orgs, err := models.GetOrganizations(c.Request().Context(), opts)
	if err != nil {
		return err
	}
	if len(orgs) == 0 {
		return echo.NotFoundHandler(c)
	}

	org := orgs[0]
	if links.BillingEnabled(gctx.Server.Config) && org.IsRestricted(
		[]int{models.BillingStatusFree, models.BillingStatusOpenSource}) {
		gmap := gobwebs.Map{
			"url":     recURL,
			"hideNav": true,
		}
		return gctx.Render(http.StatusOK, "restriction_redirect.html", gmap)
	}

	return c.Redirect(http.StatusMovedPermanently, recURL)
}

// RouteName ...
func (r *RedirectService) RouteName(value string) string {
	return fmt.Sprintf("%s:%s", r.name, value)