func (h *Handler) EndAllUserSessionsTx(ctx context.Context, tx *sql.Tx) error {
	err := permission.LimitCheckAny(ctx, permission.Admin, permission.MatchUser(permission.UserID(ctx)))
	if err != nil {
		return err
	}
	src := permission.Source(ctx)
	stmt := h.endAllSessionsUser
	if tx != nil {
		stmt = tx.StmtContext(ctx, stmt)
	}
	_, err = stmt.ExecContext(ctx, permission.UserID(ctx), src.ID)
	return err
}
EndAllUserSessionsTx ends all sessions other than the user's currently active session
package auth
import (
	"context"
	"database/sql"
	"encoding/json"
	"io"
	"net/http"
	"net/url"
	"path"
	"sort"
	"strings"
	"time"
	"github.com/google/uuid"
	"github.com/pkg/errors"
	"github.com/target/goalert/auth/authtoken"
	"github.com/target/goalert/config"
	"github.com/target/goalert/integrationkey"
	"github.com/target/goalert/permission"
	"github.com/target/goalert/user"
	"github.com/target/goalert/util"
	"github.com/target/goalert/util/errutil"
	"github.com/target/goalert/util/log"
	"github.com/target/goalert/util/sqlutil"
	"github.com/target/goalert/validation"
	"github.com/target/goalert/validation/validate"
	"go.opencensus.io/trace"
)
const CookieName = "goalert_session.2"
const v1CookieName = "goalert_session"
type registeredProvider struct {
	ID string
	URL string
	ProviderInfo
}
type Handler struct {
	providers map[string]IdentityProvider
	cfg       HandlerConfig
	db         *sql.DB
	userLookup *sql.Stmt
	addSubject *sql.Stmt
	updateUA   *sql.Stmt
	updateUser *sql.Stmt
	startSession *sql.Stmt
	fetchSession *sql.Stmt
	endSession   *sql.Stmt
	userSessions       *sql.Stmt
	endSessionUser     *sql.Stmt
	endAllSessionsUser *sql.Stmt
}
func NewHandler(ctx context.Context, db *sql.DB, cfg HandlerConfig) (*Handler, error) {
	p := &util.Prepare{
		DB:  db,
		Ctx: ctx,
	}
	h := &Handler{
		providers: make(map[string]IdentityProvider),
		db:        db,
		cfg: cfg,
		updateUser: p.P(`
			update users
			set
				name = case when $2 = '' then name else $2 end,
				email = case when $3 = '' then email else $3 end
			where id = $1
		`),
		userLookup: p.P(`
			select user_id
			from auth_subjects
			where
				provider_id = $1 and
				subject_id = $2
		`),
		addSubject: p.P(`
			insert into auth_subjects (provider_id, subject_id, user_id)
			values ($1, $2, $3)
		`),
		startSession: p.P(`
			insert into auth_user_sessions (id, user_agent, user_id)
			values ($1, $2, $3)
		`),
		endSession: p.P(`
			delete from auth_user_sessions
			where id = any($1)
		`),
		updateUA: p.P(`
			update auth_user_sessions
			set user_agent = $2
			where id = $1
		`),
		fetchSession: p.P(`
			with update as (
				update auth_user_sessions
				set last_access_at = now()
				where id = $1 AND (last_access_at isnull OR last_access_at < now() - '1 minute'::interval)
			)
			select sess.user_id, u.role
			from auth_user_sessions sess
			join users u on u.id = sess.user_id
			where sess.id = $1
		`),
		userSessions: p.P(`
			select id, user_agent, created_at, last_access_at
			from auth_user_sessions
			where user_id = $1
		`),
		endSessionUser: p.P(`
			delete from auth_user_sessions
			where user_id = $1 and id = $2
		`),
		endAllSessionsUser: p.P(`
			delete from auth_user_sessions
			where user_id = $1 and id != $2
		`),
	}
	return h, p.Err
}
type UserSession struct {
	ID           string
	UserAgent    string
	CreatedAt    time.Time
	LastAccessAt time.Time
	UserID       string
}
func (h *Handler) EndUserSessionTx(ctx context.Context, tx *sql.Tx, id ...string) error {
	err := permission.LimitCheckAny(ctx, permission.User)
	if err != nil {
		return err
	}
	if permission.Admin(ctx) {
		_, err = tx.StmtContext(ctx, h.endSession).ExecContext(ctx, sqlutil.UUIDArray(id))
	} else {
		_, err = tx.StmtContext(ctx, h.endSessionUser).ExecContext(ctx, permission.UserID(ctx), sqlutil.UUIDArray(id))
	}
	return err
}