fix cookie options

pull/6/head
Namekuji 2022-12-04 12:52:44 -05:00
rodzic 059ab019d6
commit da13f2f55c
7 zmienionych plików z 121 dodań i 49 usunięć

Wyświetl plik

@ -15,6 +15,7 @@ export default {
data() {
return {
server: "",
serverErr: "",
};
},
validations() {
@ -31,7 +32,11 @@ export default {
computed: {
serverErrors() {
const errors = this.v$.server.$errors;
return _.map(errors, (e) => e.$message);
const messages = _.map(errors, (e) => e.$message);
if (this.serverErr !== "") {
messages.push(this.serverErr);
}
return messages;
},
},
methods: {
@ -40,12 +45,25 @@ export default {
if (!isFormCorrect) {
return;
}
const response = await axios.postForm("/api/login", { server: this.server });
if (response.status === 201) {
// this.$router.push(response.data)
location.assign(response.data)
try {
const response = await axios.postForm("/api/login", {
server: this.server,
});
if (response.status === 201) {
// this.$router.push(response.data)
location.assign(response.data);
this.serverErr = "";
}
} catch (error) {
if (error.response && error.response.status === 404) {
this.serverErr = "サーバーが見つかりません"
}
}
},
onInput () {
this.v$.server.$touch();
this.serverErr = "";
}
},
};
</script>
@ -60,8 +78,7 @@ export default {
placeholder="mastodon.example"
class="mb-2"
:error-messages="serverErrors"
@input="v$.server.$touch"
@blur="v$.server.$touch"
@update:model-value="onInput"
clearable
/>
<v-btn block @click="onSubmit" :disabled="!v$.$dirty || v$.$error"

Wyświetl plik

@ -12,12 +12,13 @@ type (
AppConfigBase
Livekit *LivekitConfig
MongoURL *url.URL
Database *DBConfig
}
AppConfigBase struct {
Database *DBConfig
SeesionSecret string `validate:"required,ascii"`
LocalDomain string `validate:"required,hostname|hostname_port"`
Environment string `validate:"printascii"`
}
LivekitConfig struct {
@ -60,6 +61,7 @@ func loadConfig(envname string) (*AppConfig, error) {
basicConf := AppConfigBase{
SeesionSecret: os.Getenv("SESSION_SECRET"),
LocalDomain: os.Getenv("LOCAL_DOMAIN"),
Environment: envname,
}
if basicConf.SeesionSecret == "" {
basicConf.SeesionSecret = "dev"

Wyświetl plik

@ -11,6 +11,8 @@ services:
MONGO_INITDB_ROOT_PASSWORD: example
ports:
- 27017:27017
volumes:
- db:/data/db
mongo-express:
image: mongo-express
@ -21,3 +23,16 @@ services:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: example
ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/
# redis:
# restart: always
# image: redis
# healthcheck:
# test: ['CMD', 'redis-cli', 'ping']
# ports:
# - 6379:6379
# volumes:
# - audon:/data
volumes:
db:

Wyświetl plik

@ -14,19 +14,20 @@ import (
)
func verifyTokenInSession(c echo.Context, sess *sessions.Session) (valid bool, err error) {
mastConf, err := getSessionData(sess)
data, err := getSessionData(sess)
if err != nil {
return false, err
}
if mastConf.MastodonConfig.AccessToken == "" {
if data.MastodonConfig.AccessToken == "" {
return false, nil
}
mastoClient := mastodon.NewClient(mastConf.MastodonConfig)
mastoClient := mastodon.NewClient(data.MastodonConfig)
_, err = mastoClient.VerifyAppCredentials(c.Request().Context())
acc, err := mastoClient.GetAccountCurrentUser(c.Request().Context())
user, dbErr := findUserByID(c.Request().Context(), data.AudonID)
if err != nil {
if err != nil || dbErr != nil || string(acc.ID) != user.RemoteID {
return false, err
}
@ -129,7 +130,7 @@ func oauthHandler(c echo.Context) (err error) {
// return echo.NewHTTPError(http.StatusInternalServerError)
// }
entropy := ulid.Monotonic(rand.Reader, 0)
id, err := ulid.New(ulid.Timestamp(time.Now()), entropy)
id, err := ulid.New(ulid.Timestamp(time.Now().UTC()), entropy)
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusInternalServerError)
@ -139,7 +140,7 @@ func oauthHandler(c echo.Context) (err error) {
AudonID: data.AudonID,
RemoteID: string(acc.ID),
RemoteURL: acc.URL,
CreatedAt: time.Now(),
CreatedAt: time.Now().UTC(),
}
if _, insertErr := coll.InsertOne(c.Request().Context(), newUser); insertErr != nil {
c.Logger().Error(insertErr)

28
room.go
Wyświetl plik

@ -45,33 +45,37 @@ func createRoomHandler(c echo.Context) (err error) {
}
room.Host = host
now := time.Now().UTC()
if now.Sub(room.ScheduledAt) > 0 {
room.ScheduledAt = now
}
// If CoHosts are already registered, retrieve their AudonID
for i, cohost := range room.CoHost {
cohostUser, err := findUserByRemote(c.Request().Context(), cohost.RemoteID, cohost.RemoteURL)
if err == nil {
room.CoHost[i].AudonID = cohostUser.AudonID
room.CoHost[i] = cohostUser
}
}
roomToken, err := getHostToken(room.RoomID, host.AudonID)
if err != nil {
c.Logger().Error(err)
room.CreatedAt = now
coll := mainDB.Collection(COLLECTION_ROOM)
if _, insertErr := coll.InsertOne(c.Request().Context(), room); insertErr != nil {
c.Logger().Error(insertErr)
return echo.NewHTTPError(http.StatusInternalServerError)
}
return c.JSON(http.StatusCreated, roomToken)
return c.String(http.StatusCreated, room.RoomID)
}
func getHostToken(room, identity string) (string, error) {
func getHostToken(room *Room) (string, error) {
at := auth.NewAccessToken(mainConfig.Livekit.APIKey, mainConfig.Livekit.APISecret)
grant := &auth.VideoGrant{
Room: room,
RoomJoin: true,
RoomRecord: true,
Room: room.RoomID,
RoomJoin: true,
}
at.AddGrant(grant).
SetIdentity(identity).
SetValidFor(24 * time.Hour)
at.AddGrant(grant).SetIdentity(room.Host.AudonID).SetValidFor(10 * time.Minute)
return at.ToJWT()
}

Wyświetl plik

@ -19,21 +19,20 @@ type (
AudonUser struct {
AudonID string `bson:"audon_id" json:"audon_id" validate:"alphanum"`
RemoteID string `bson:"remote_id" json:"remote_id" validate:"alphanum"`
RemoteID string `bson:"remote_id" json:"remote_id" validate:"printascii"`
RemoteURL string `bson:"remote_url" json:"remote_url" validate:"url"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
}
Room struct {
RoomID string `bson:"room_id" json:"room_id" validate:"required,alphanum"`
Title string `bson:"title" json:"title" validate:"required,alphanumunicode"`
Description string `bson:"description" json:"description" validate:"alphanumunicode"`
RoomID string `bson:"room_id" json:"room_id" validate:"required,printascii"`
Title string `bson:"title" json:"title" validate:"required,printascii|multibyte"`
Description string `bson:"description" json:"description" validate:"printascii|multibyte"`
Host *AudonUser `bson:"host" json:"host"`
CoHost []*AudonUser `bson:"cohost" json:"cohost"`
FollowingOnly bool `bson:"following_only" json:"following_only" validate:"required"`
FollowerOnly bool `bson:"follower_only" json:"follower_only" validate:"required"`
InviteOnly bool `bson:"invite_only" json:"invite_only" validate:"required"`
InviteToken string `bson:"invite_token" json:"invite_token" validate:"alphanum"`
FollowingOnly bool `bson:"following_only" json:"following_only"`
FollowerOnly bool `bson:"follower_only" json:"follower_only"`
MutualOnly bool `bson:"mutual_only" json:"mutual_only"`
ScheduledAt time.Time `bson:"scheduled_at" json:"scheduled_at"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
}
@ -47,12 +46,15 @@ const (
func createIndexes(ctx context.Context) error {
userColl := mainDB.Collection(COLLECTION_USER)
userIndexes, err := userColl.Indexes().ListSpecifications(ctx)
if err != nil {
return err
}
if len(userIndexes) < 3 {
_, err := userColl.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.D{{Key: "audon_id", Value: 1}},
Options: options.Index().SetName("audon_id_1").SetUnique(true),
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{
@ -66,7 +68,28 @@ func createIndexes(ctx context.Context) error {
}
}
return err
roomColl := mainDB.Collection(COLLECTION_ROOM)
roomIndexes, err := roomColl.Indexes().ListSpecifications(ctx)
if err != nil {
return err
}
if len(roomIndexes) < 3 {
_, err := roomColl.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.D{{Key: "room_id", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "host.audon_id", Value: 1}},
},
})
if err != nil {
return err
}
}
return nil
}
func findUserByRemote(ctx context.Context, remoteID, remoteURL string) (*AudonUser, error) {

Wyświetl plik

@ -56,15 +56,17 @@ func main() {
os.Exit(1)
}
dbContext, cancel := context.WithTimeout(context.Background(), 5*time.Second)
backContext, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
dbClient, err := mongo.Connect(dbContext, options.Client().ApplyURI(mainConfig.MongoURL.String()))
// Setup database client
dbClient, err := mongo.Connect(backContext, options.Client().ApplyURI(mainConfig.MongoURL.String()))
if err != nil {
log.Fatalln(err)
os.Exit(2)
}
mainDB = dbClient.Database(mainConfig.Database.Name)
err = createIndexes(dbContext)
err = createIndexes(backContext)
if err != nil {
log.Fatalln(err)
os.Exit(3)
@ -78,7 +80,23 @@ func main() {
}
e.Renderer = t
e.Validator = &CustomValidator{validator: mainValidator}
e.Use(session.Middleware(sessions.NewCookieStore([]byte(mainConfig.SeesionSecret))))
cookieStore := sessions.NewCookieStore([]byte(mainConfig.SeesionSecret))
cookieStore.Options = &sessions.Options{
Path: "/",
Domain: mainConfig.LocalDomain,
MaxAge: 86400 * 30,
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
Secure: true,
}
if mainConfig.Environment == "development" {
cookieStore.Options.Domain = ""
cookieStore.Options.SameSite = http.SameSiteNoneMode
cookieStore.Options.Secure = false
cookieStore.Options.MaxAge = 3600 * 24
cookieStore.Options.HttpOnly = false
}
e.Use(session.Middleware(cookieStore))
// e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// CookiePath: "/",
// TokenLookup: "header:X-XSRF-TOKEN",
@ -164,14 +182,6 @@ func getSession(c echo.Context) (sess *sessions.Session, err error) {
return nil, err
}
sess.Options = &sessions.Options{
Path: "/",
MaxAge: 0,
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
Secure: true,
}
return sess, nil
}